管理还原数据

UNDO表空间管理1、对于DML语句来说,只要修改了数据块,Oracle数据库就会将修改前的数据块保留下来,保存在undosegment里面,而undosegment则保存在undo表空间中

undo 表空间管理

1、对于DML语句来说,只要修改了数据块,Oracle数据库就会将修改前的数据块保留下来,保存在undo segment里面,而undo segment则保存在undo表空间中

2、undo的管理

自动undo管理(Oracle9i开始)AUM

手工undo管理MUM

9i以后,就建议使用AUM,因此就不再讨论MUM

一条DML语句的执行流程update t set coll=‘A’ where coll=‘B’

1、在shared pool里面进行解析,从而生成执行计划

2、根据执行计划,得出coll=‘B’的记录存放在10号数据文件的54号数据块里面

3、服务器进程首先在buffer cache寻找一个可用的undo数据块(如果一个事物已经提交,那么这个事务曾经使用过的undo数据块就可以被使用),如果没有发现,则到undo表空间里找到一个可用的undo数据块,并调入到buffer cache。假设获得的undo数据块号为24号,位于11号undo数据文件里

4、将改变前的值,也就是B放入24号undo数据块(buffer cache中)

5、由于undo数据块发生了变化(只要是数据块发生变化,那么就产生重做记录),于是产生重做记录,假设重做记录号是120

6、在buffer cache里面找到54号数据块,如果没有,则从10号数据文件调入

7、将改变后的值,也就是A放入54号数据块

8、由于数据块发生了变化,于是产生重做记录,假设重做记录号是121

9、控制权返回给用户,如果使用SQLPLUS,那么表现为光标返回

10、用户发出commit命令,触发LGWR,将120、121这两个重做记录写入联机重做日志文件中,将54号、24号两个数据块头部所记录的事务状态标记设置为已提交,控制权返回给用户,如果使用SQLPLUS,那么表现为光标返回

11、这个时侯,54号和24号数据块并不一定被DBWr写入数据文件,只有在脏数据块的数量达到一定程度的时候才会被写入

事务提交以后,该事务所使用的undo数据块就可以被覆盖,上面的例子中,第10步用户提交以后,24号undo数据块就可以被覆盖

Undo的作用

1、提供读一执性

2、回滚事务

3、实例恢复

读一致性

一个场景描述

读一致性是相对脏读而言的,表T中有10000条记录,获取所有的记录需要15分钟的时间,当前时间为9点整,香港服务器,用户发出一条select * from T命令,该语句在9:15完成。当用户执行该语句到9:10分的时候,另外一个用户发出了一条删除命令,将最后一条记录删除,并且进行了提交。

到9点15分的时候,用户返回了多少条记录。

如果是9999条,那么就是脏读、如果是10000条,那么就是读一致性。

Oracle不会出现脏读,提供读一致性,而且没有阻塞DML操作

Oracle如何实现读一致性呢?

1、用户在9点发出select语句的时候,服务器进程会记录9点那个时刻的SCN号(SCN号是以时间(timestamp)作为参数的一个函数返回值,调用函数(默认以timestamp为参数)随时可以返回这个时刻的SCN号,可以使用函数在SCN和timestamp之间进行转换),假设该SCN号是SCN9:00,那么SCN9:00一定大于等于记录在所有数据块头部的ITL槽中的SCN号(如果有多个ITL槽,SCN最大的那个)

2、服务器进程扫描T表的时候,会把扫描的数据块头部的ITL槽中的SCN号与SCN9:00进行比较,哪个更大。如果数据块头部的SCN小于SCN9:00,那么说明这个数据块在9:00以后没有更改过,可以直接读取,如果数据块头部的SCN号大于SCN9:00,则说明该数据块在9:00以后更改过,已经不是9:00那个时刻的数据了于是要借助undo块

3、9点10分,用户更改了T表的最后一条记录并提交(无论是否提交,只要是更改了T表,用户就会去读undo数据块),假设被更改的是N号数据块,那么N号数据块头部的ITL槽中记录的SCN被修改为SCN9:10,当服务器进程扫描到这个数据块的时候,发现ITL槽中的SCN9:10大于SCN9:00,说明该数据块在9:00以后被更新了,于是服务器进程到N号块的头部,找到SCN9:10所在ITL槽,由于ITL槽记录了对应的undo块的地址,于是服务器进程找到undo数据块,结合undo数据块给用户提供读一致性。

进一步复杂化问题

1、9点10分,更新了数据并且进行了提交,9点11分又对该数据块进行了更新并且提交(假设数据块只有一个ITL槽)

2、那么该ITL槽记录的就是SCN9:11

3、这种情况如何处理,秘密在于undo数据块中,除了记录改变前的数据以外,因为数据块的ITL槽也发生了变化,因此也进行了记录,而ITL槽中记录了undo块的地址。9:00的时候数据块的ITL槽中记录了数据块的SCN是8:50和对应的undo块,9:10分的时候数据库的ITL槽中记录了数据块的SCN是9:10和对应的undo(undo1),9:11分的时候数据库的ITL槽中记录了数据块的SCN是9:11和对应的undo(undo2),Undo2中记录了9:10的数据,以及9:10数据的undo地址undo1,undo1中记录了9点以前的数据以及9点以前的undo数据

当用户进行查询的时候,服务器进程扫描到N号数据块,发现SCN9:11,大于SCN9:00,从ITL槽中找到undo块的地址(undo2),undo2中记录了改变前的数据和改变前的数据库的ITL槽,发现undo2对应的SCN是9:10还是大于9:00,根据undo里面记录的ITL槽的改变前信息,继续向前找,找到undo1,发现SCN是8:50,小于9:00,使用这个undo的数据

如果在向前寻找的时候,没有找到SCN小于9:00的数据(因为时间比较长,而且事务已经提交,所以回滚段可能被覆盖),数据库就会出现一个经典的错误ORA-01555(snapshoot too old),但是不会出现脏读的情况。

clip_image003

最核心的就是:数据块的数据发生改变,ITL槽也发生改变。这两条信息都会存储到undo中。因此如果一个undo足够的大,那么一个数据块的所有的undo数据块是可以串联起来的。可以从最近一直找到非常远的过去。从数据块开始往前找,一直找到很久以前的SCN。这个数据块所有的变化都能够找到。

ITL槽中记录着这个数据块的undo数据块的地址。

一个数据块中存储很多条数据,update、insert、delete等DML操作,都会影响数据块的SCN号。数据块的SCN号反映了数据块的变化过程。

回滚事务:错误或者rollback命令都会产生回滚

根据ITL槽中记录的undo数据块的地址,找到undo数据块,恢复数据。

实例恢复

乾坤圈新媒体矩阵管家 乾坤圈新媒体矩阵管家

新媒体账号、门店矩阵智能管理系统

乾坤圈新媒体矩阵管家 17 查看详情 乾坤圈新媒体矩阵管家

回滚段的头部记录了事务表,每一个事务是否提交等信息都存储在里面。

根据事务表的信息进行实例恢复。

配置AUM

Oracle9i开始,我们不再使用手工的管理方式,因此“MANUAL”不再使用,使用“AUTO”

使用AUM需要配置两个参数

clip_image004

指定这两个参数以后,剩余的工作让Oracle来处理,例如undo segment的创建、扩展、收缩、删除等。

如果指定了undo_management,但是在指定undo_tablespace的时候,指定了一个错误的回滚表空间,实例启动的时候,会报错。

如果没有指定回滚段表空间,系统查找第一个可用的回滚段表空间,如果没有找到,那么就使用system表空间中的回滚段,这不是我们希望看到的,因为对性能影响很大。

因此两个参数都要很好的规划

事务、undo segment

发生DML操作的时候,服务器进程会选择一个undo segment,具体算法如下:

1、首先尝试将每一个undo segment绑定一个事务,也就是每个undo segment上只有一个事务使用

2、如果不能发现完全空闲的undo segment,所有的undo segment都与事务绑定

3、系统尝试将脱机的undo segment联机

4、如果没有可用的undo segment进行联机,则会尝试创建一个新的undo segment

5、如果上面的步骤都没有成功(例如没有可用空间了,不能创建undo segment),算法会尝试寻找最早使用的undo segment,这种情况下,不同的多个事务会在同一个相同的undo segment里同时进行

6、每隔12个小时会收缩一次,删除那些idle状态的extent

7、DML操作需要undo时,发现空间不够,则会唤醒SMON进行一次收缩,将undo segment里面暂时没有使用的extent拿过来使用

Oracle 在提供一致性读的过程中,具体的步骤如下

1、确认读时刻的SCN

2、搜寻所有的数据块的SCN要求小于读时刻的SCN

3、如果搜寻的SCN小于读时刻的SCN,直接读取

4、如果搜寻的SCN大于读时刻的SCN,根据数据块里面的ITL槽里面记录的undo信息,找到改变前的数据、如果SCN还是大,顺着ITL槽信息串联起来的undo块继续向前找

5、如果没有找到小于读时刻的SCN的数据块,那么就报错ORA-01555

事务提交以后,undo回滚段就可以被覆盖,而且我们在寻找undo数据块的时候,这个被寻找的undo数据块很可能已经被提交,因此出现ORA-01555错误不可避免。Oracle是如何来解决这个问题的呢?

Oracle定义了一个参数undo_retention

这个参数以秒为单位,表示当事务提交或者回滚以后,该事务所使用的undo 块里的数据需要保留多长时间。

当保留的时间超过undo_retention所指定的时间以后,该undo块才能够被其他事务覆盖。

当我们使用AUM的时候,并且设置了undo_retention以后,undo块的状态就存在4种

Active:表示正在使用该数据块的事务还没有提交或者回滚

Inactive:该数据块上没有活动的事务,该状态的undo可以被其他事务覆盖

Expired:该数据块持续inactive的时间超过undo_retention所指定的时间

Freed:该数据块是空的,从来没有被使用过

在AUM模式中,事务可以在不同的undo segment之间动态交换undo空间,也就是在不同的undo segment里交换extents。

我们来看一下,一个事务需要更多的undo空间的时候,是如何进行处理的?

1、获取undo表空间里可用的、空的extents(segment的最小分配单元是extent)

2、获取其他undo segment里的expired状态的extents

3、如果undo表空间里的数据文件启用了自动扩展,则数据文件进行自动扩展

4、如果undo表空间里的数据文件没有启用自动扩展,则获取undo segment里的inactive状态的extents

5、如果还是没有获得可用空间,报空间不足的错误

clip_image006

1、undo表空间中一共存在5个undo segment

2、每个undo segment包括7个extents

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 chuangxiangniao@163.com 举报,一经查实,本站将立刻删除。
发布者:程序猿,转转请注明出处:https://www.chuangxiangniao.com/p/529492.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2025年11月9日 09:47:24
下一篇 2025年11月9日 09:52:27

相关推荐

  • MySQL INSERT 语句可读性优化:利用 SET 语法提升代码清晰度

    本文探讨了在mysql中优化`insert`语句可读性的方法。针对传统`insert … values`语法在处理大量列时难以匹配值与列名的问题,推荐使用`insert … set`语法。这种方式能显著提升sql语句的清晰度,使开发者更容易理解和维护代码,尤其适用于go等语言…

    2025年12月16日
    000
  • 提升MySQL INSERT 语句清晰度:SET 语法详解

    本文旨在解决sql `insert` 语句在处理大量字段时可读性差的问题。传统 `values` 列表语法使得列与值难以对应,降低了代码清晰度。我们将介绍并详细阐述mysql中更为优雅的 `insert … set` 语法,通过直接将列与值关联,显著提升语句的可读性和维护性,特别适用于需…

    2025年12月16日
    000
  • 深入探讨Go语言crypto库与OpenSSL的安全性对比及生产环境考量

    本文探讨go语言标准库crypto/tls在生产环境中的安全性,并与openssl进行比较。go的tls实现存在已知侧信道攻击风险,且缺乏外部安全审计,因此在某些关键场景下可能不足以满足生产需求。文章分析了具体漏洞,并指出在go标准库层面,目前尚无官方推荐的go调用openssl库的方法。 Go语言…

    2025年12月16日
    000
  • Go lib/pq驱动中PostgreSQL SQL占位符的正确使用指南

    在使用go语言的`lib/pq`驱动连接postgresql时,sql查询中的占位符应采用`$n`(如`$1`、`$2`)而非通用的`?`。本文将详细解释这一postgresql特有的语法要求,并通过示例代码演示如何正确地构建和执行参数化查询,从而避免常见的语法错误,确保数据库操作的安全性与高效性。…

    2025年12月16日
    000
  • OAuth响应处理与安全会话管理:数据库集成与Cookie最佳实践

    本教程深入探讨了OAuth2认证流程结束后,如何安全高效地处理用户数据并建立会话。文章首先介绍了将OAuth提供者返回的用户数据存储到数据库的最佳实践,重点讲解了原子性的UPSERT操作以避免数据冗余和竞态条件。随后,详细阐述了基于Cookie的会话管理策略,强调了使用HTTPS、Secure、Ht…

    2025年12月16日
    000
  • Golang如何实现自动化备份与恢复

    Go语言适合构建自动化备份与恢复系统,其核心是通过调用系统命令或API实现数据备份与恢复。1. 文件备份可使用os和io包复制文件,数据库备份可通过mysqldump等工具或驱动导出;2. 使用robfig/cron库设置定时任务,如每日2点执行备份,并结合systemd或Kubernetes管理任…

    2025年12月16日
    000
  • Golang集成数据库客户端开发环境配置

    首先安装Go环境并配置GOROOT、GOBIN与PATH,验证go version;接着通过go mod init创建项目,使用go get引入如github.com/go-sql-driver/mysql等对应数据库驱动,并在代码中匿名导入以注册驱动;然后调用sql.Open()传入驱动名和DSN…

    2025年12月15日
    000
  • Golang测试代码生成 自动化生成测试用例

    自动化生成Golang测试用例的核心在于结合Fuzzing、反射和代码生成工具。Go内置Fuzzing能自动探索输入并发现崩溃,解决输入多样性问题;反射可用于自动生成复杂结构体的测试数据,提升数据准备效率;gopter等PBT库则通过定义代码属性验证逻辑正确性;而外部依赖模拟和“神谕问题”仍需人工设…

    2025年12月15日
    000
  • Golang的crypto库如何实现数据加密 演示AES和RSA最佳实践

    golang的crypto库为数据加密提供了坚实的基础,它不是一个单一的“加密”功能,而是一系列密码学原语的集合。在实际应用中,aes(高级加密标准)凭借其对称加密的高效性,成为处理大量数据的首选,尤其是在gcm模式下,它能同时提供数据的机密性、完整性和认证。而rsa(rivest-shamir-a…

    2025年12月15日 好文分享
    000
  • Golang如何优化加密运算 使用硬件加速指令提升AES性能

    要优化golang中的aes加密性能,关键在于利用硬件加速和高效模式。1. 使用标准库crypto/aes包,其已自动启用aes-ni指令;2. 确认cpu支持aes-ni;3. 采用gcm模式提升性能与安全性;4. 复用cipher实例避免重复初始化;5. 利用并发处理大数据块;6. 减少内存拷贝…

    2025年12月15日 好文分享
    000
  • Golang数据库操作指南_go连接MySQL实战

    golang连接mysql需使用database/sql包及驱动。1.安装推荐的mysql驱动github.com/go-sql-driver/mysql;2.通过sql.open创建连接池并用db.ping测试连接;3.查询时使用rows.scan读取数据并确保关闭rows;4.更新操作使用db.…

    2025年12月15日 好文分享
    000
  • Debian系统如何监控JSP应用的运行状态

    在Debian操作系统中,对JSP应用进行运行状态监控可以采用多种方式和相关工具。以下是一些常见的方法: 1. 利用SpringBoot内置的性能监控功能 如果JSP项目是基于SpringBoot构建的,可以使用其自带的性能监控组件。SpringBoot提供了一些基础的监控类,比如Performan…

    2025年12月15日
    000
  • Debian下sqlplus使用技巧有哪些

    在Debian操作系统中使用SQL*Plus时,掌握一些实用技巧可以显著提升操作效率和管理体验。以下是一些常用的技巧: 增强命令行操作:通过安装rlwrap工具来实现命令历史浏览和上下文切换功能。具体步骤如下: sudo apt-get install rlwrap echo “alias sqlp…

    2025年12月15日
    000
  • 如何在Debian中提高phpstorm的稳定性

    在Debian系统中增强PhpStorm的稳定性可通过以下几种方式实现: 维持软件更新: 定期将PhpStorm升级至最新版本,例如PhpStorm 2018.1版本包含了大量错误修正及功能优化。同时也要确保Debian系统的全面更新,这样可以有效规避潜在的兼容性冲突。 选择合适的JVM: PhpS…

    2025年12月15日
    000
  • 使用Go语言连接Oracle数据库时是否需要安装Oracle客户端?

    Go语言连接Oracle数据库:是否必须安装Oracle客户端? 在Go语言开发中连接Oracle数据库是常见需求。许多教程和示例都建议安装Oracle客户端,这在Windows桌面开发和Linux生产环境中可能带来配置上的差异和不便。那么,Go语言的Oracle数据库驱动程序能否绕过Oracle客…

    2025年12月15日
    000
  • 在Go语言中使用Oracle驱动是否需要安装Oracle客户端?

    Go语言连接Oracle数据库:是否需要Oracle客户端? 许多Go语言开发者在连接Oracle数据库时,都会纠结于是否需要安装Oracle客户端。网上的许多示例都依赖于Oracle客户端,这无疑增加了跨平台部署的复杂性(例如,开发环境为Windows,生产环境为Linux)。 那么,Go语言的O…

    2025年12月15日
    000
  • 在Go中使用Oracle数据库驱动是否需要安装Oracle客户端?

    Go语言连接Oracle数据库:Oracle客户端并非必需 在Go语言开发中连接Oracle数据库,开发者常面临一个关键问题:是否必须安装Oracle客户端?尤其在Windows开发环境与Linux生产环境切换时,这个问题显得尤为重要。 许多教程都包含安装Oracle客户端的步骤,这无疑增加了开发和…

    2025年12月15日
    000
  • python oracle数据库如何安装?

    首先安装Oracle Instant Client并配置环境变量,再通过pip install oracledb安装Python驱动,最后用代码测试连接;确保客户端版本与系统匹配,并正确设置PATH、LD_LIBRARY_PATH或DYLD_LIBRARY_PATH以避免常见错误。 要在Python…

    2025年12月14日
    000
  • python-oracledb 游标对象与数据库会话管理深度解析

    本文深入探讨 `python-oracledb` 库中游标对象(Cursor Object)及其变量(Cursor Variable)的工作原理与生命周期。我们将阐明 `cursor.var()` 创建的变量在 Python 客户端和 Oracle 数据库会话之间的关系,纠正关于其值持久性的常见误解…

    2025年12月14日
    000
  • SQLAlchemy 声明式模型中指定数据库表模式(Schema)的方法

    本文详细介绍了如何在使用 sqlalchemy 声明式 api 定义和创建数据库表时,指定表所属的数据库模式(schema)。通过在声明式模型类中利用 `__table_args__` 属性并设置 `schema` 参数,开发者可以精确控制表在数据库中的位置,从而避免默认的“public”模式,尤其…

    2025年12月14日
    000

发表回复

登录后才能评论
关注微信