首页 > 数据库 >生产数据恢复系列之使用闪回查询恢复Oracle delete误删数据

生产数据恢复系列之使用闪回查询恢复Oracle delete误删数据

时间:2024-10-22 18:18:12浏览次数:8  
标签:数据恢复 闪回 name 1024 undo test Undo SQL Oracle

一、背景

在日常运维过程中,如果不小心使用高危命令删除了数据库的数据,如果没有数据备份,记住不要跑路噢,跟着我一起学习如何恢复数据。

二、概念普及

UNDO表的作用
Undo 表存储了已提交和未提交事务所产生的旧数据版本,在需要回滚事务或实现并发控制时使用。每当对数据库进行DML操作时(例如插入、更新或删除记录),Oracle 就会在 undo 表中保存之前数据的副本,在需要的时候回滚。
事务回滚: 当事务需要回滚时,Oracle 可以使用 undo 表中的数据来还原到事务开始之前的状态,确保数据的一致性和完整性。
并发控制: 在并发访问数据库时,多个事务可能同时修改相同的数据。Undo 表允许数据库保持一致性,确保每个事务在读取和修改数据时都能看到正确的数据版本。
读一致性: 当一个事务正在修改数据时,其他事务可能需要读取一致性的数据。Undo 表使得其他事务可以读取在当前事务修改之前的数据版本,从而实现读一致性。
闪回查询: 使用闪回查询功能,可以利用 undo 表中的数据来恢复数据库中的特定时间点的数据状态,而无需从备份进行还原。

dml产生的undo的量:
在dml操作提交前,能够进行回滚操作,回滚信息就是从undo段中读取的。
回滚等效于反向操作。undo不会记录语句,记录的是数据的变化。
insert产生undo 仅仅记录rowid
delete 产生undo, 记录改行所有信息
update 产生undo,改动前后的字段。

三、场景模拟

今天来模拟使用delete误删数据后采用使用闪回查询恢复表到过去某一个时间点。oracle闪回查询使用的是undo表空间,闪回查询能恢复的时间点取决于undo表空间的大小和Undo_Retention参数有关。

1、查看undo表空间的大小和保留时间
SQL>SELECT VALUE/60 AS "UNDO_RETENTION_MINUTES" FROM V$PARAMETER WHERE NAME = 'undo_retention';

SQL>select name from v$tablespace; #查看Undo库文件
SQL>SELECT value AS default_undo_tablespace FROM v$parameter WHERE name = 'UNDOTBS1'; #查看默认回滚表空间名
SQL>select s.STATUS,sum(s.BYTES)/1024/1024 from DBA_UNDO_EXTENTS s group by s.STATUS; #查看undo表空间占用大小
SQL>SELECT tablespace_name, ROUND(bytes / (1024 * 1024 * 1024), 2) AS size_gb,file_name FROM dba_data_files; #查看undo文件存放的位置
SQL>SELECT d.tablespace_name,
       ROUND((NVL(a.total, 0) - NVL(f.free, 0)) / 1024 / 1024, 2) AS used_undo_space_mb,
       ROUND(NVL(f.free, 0) / 1024 / 1024, 2) AS free_undo_space_mb,
       ROUND(NVL(a.total, 0) / 1024 / 1024, 2) AS total_undo_space_mb,
       ROUND(NVL(a.total, 0) / 1024 / 1024 - NVL(f.free, 0) / 1024 / 1024, 2) AS remaining_undo_space_mb
  FROM dba_tablespaces d,
       (SELECT tablespace_name, SUM(bytes) total FROM dba_data_files GROUP BY tablespace_name) a,
       (SELECT tablespace_name, SUM(bytes) free FROM dba_free_space GROUP BY tablespace_name) f
WHERE d.tablespace_name = a.tablespace_name(+)
  AND d.tablespace_name = f.tablespace_name(+)
  AND d.contents = 'UNDO'; #查看数据库UNDO表空间占用空间情况

SQL> ALTER SYSTEM SET UNDO_RETENTION = 36000; 将UNDO_RETENTION 被设置为 3600 秒(即 1 小时),最长可设置为24小时。

2、创建测试表空间、用户和角色
[oracle@myoracle orcl11g]$ mkdir -p /u01/app/oracle/oradata/ceshi #创建存放表空间的目录
SQL> create tablespace ceshi datafile '/u01/app/oracle/oradata/ceshi/ceshi.dbf' size 100M autoextend on next 10M MAXSIZE  500M;
SQL>create user test identified by 123456 default tablespace ceshi;
SQL> grant dba to test;
SQL> commit;
SQL> conn test/123456

3、创建测试表
(1)创建一个简单的测试表
SQL>CREATE TABLE test (id NUMBER PRIMARY KEY,data VARCHAR2(100));

(2)插入测试数据
SQL>INSERT INTO test (id, data) VALUES (1, 'Sample data 1');
SQL>INSERT INTO test (id, data) VALUES (2, 'Sample data 2');
SQL>INSERT INTO test (id, data) VALUES (3, 'Sample data 3');
SQL> commit;

(3)查询测试数据
SQL>SELECT * FROM test;

(4)模拟使用delete删除数据
SQL>delete from test where id=2; 

四、数据恢复

1、查看所有表的创建和最后修改时间
SQL>SELECT OBJECT_NAME, CREATED, LAST_DDL_TIME from user_objects;
查看特定表的创建和最后修改时间
SQL>select CREATED,LAST_DDL_TIME from user_objects where object_name=upper('test');

2、创建一个临时表,使用AS OF TIMESTAMP进行恢复
方法1:查询1分钟之前的数据
SQL> select * from test as of timestamp (systimestamp - interval '1' minute);  #写法1
SQL> select * from test  as of timestamp sysdate - 1/1440; #写法2

方法2:指定恢复到某个时间节点
SQL>create table tmp as select * from test AS OF TIMESTAMP to_timestamp('2024-09-28 17:55:00','yyyy-mm-dd hh24:mi:ss'); #此时间段也是根据操作时间进行预估

SQL>SELECT * FROM tmp; # 查询数据


转化为insert语句

SQL> SELECT 'INSERT INTO test (id, data) VALUES(' || '''' || id || '''' || ',' || '''' || data || '''' || ');' FROM tmp ORDER BY id;

**插入恢复的数据**
SQL> INSERT INTO test (id, data) VALUES('2','Sample data 2');
SQL> select * from test;

五、总结

闪回查询能恢复的时间点取决于undo表空间的大小和Undo_Retention参数有关。如果系统中Undo管理比较不合理,事务Undo数据量比较大而且频繁,有失效的Undo前镜像被覆盖之后,恰恰有一个长时间查询需要访问这个前镜像。这个时候,不好恢复了。
事实上,Undo_retention是一个“目标期望值”。用户设置出这个值之后,Oracle内部会尽量保证将Undo数据保留超过undo_retention设置的时间。在这个过程中,Oracle会涉及到比如尝试拓展Undo表空间数据文件、Undo Segment管理等内容。但是,如果“现实比较残酷”,比如说Undo使用紧张、没有额外的方法,那么这个时间段也是不能保证的。
还有一种方式是使用闪回功能,但生产中一般不建议开启闪回功能,闪回也属于杀敌一千自损八百。
欢迎关注公众号《小周的数据库进阶之路》,更多精彩知识和干货尽在其中。
在这里插入图片描述

标签:数据恢复,闪回,name,1024,undo,test,Undo,SQL,Oracle
From: https://blog.csdn.net/qq_36936192/article/details/143117010

相关文章

  • oracle重启及impdb导入
    oracle重启停止Oracle服务sqlplus/assysdbashutdownimmediate;停止Oracle监听器sqlplus/assysdbalsnrctlstop;从Oracle安装用户开启sqlplus/assysdbastartupexit启动监听器$ORACLE_HOME/bin/lsnrctlstartimpdb导入创建逻辑目录sqlplus/assysdba......
  • 闪迪SanDisk固态硬盘维修数据恢复
    固态硬盘(SSD)维修和数据恢复是一个复杂的过程,涉及多个步骤和工具。以下是一些关键的步骤和建议,以帮助您有效地进行固态硬盘的维修和数据恢复:一、固态硬盘维修检查连接:打开计算机主机箱,检查固态硬盘的SATA或NVMe接口连接线是否插紧,是否有松动或断裂。重新插拔连接线,然后重启计算......
  • RAID5数据恢复—raid5阵列如何重组?raid5阵列重组方法详解
    RAID5数据恢复环境:一台存储上有一组由12块SCSI硬盘(11块数据盘+1块热备盘)组建的RAID5磁盘阵列,FreeBSD操作系统+zfs文件系统。RAID5故障:其中一块盘出现故障,需要重组该raid5磁盘阵列。RAID5数据恢复过程:1、将存储关机,将存储中所有磁盘标记后从槽位上取出。以只读方式将所有磁盘进......
  • 简单了解Oracle数据库中如何创建索引
    首发微信公众号:SQL数据库运维原文链接:https://mp.weixin.qq.com/s?__biz=MzI1NTQyNzg3MQ==&mid=2247486530&idx=1&sn=e5132af812a8fda7d86e1f17ecaf3a17&chksm=ea375832dd40d124027c20849d71e1c55efdd89e9ddf6e93cf310926097ea6fe14424f5187c8&token=2092690319&la......
  • Oracle EBS总账与会计假设
    OracleEBS系统的总账模块体现会计假设主要通过以下几个方面:会计科目表(ChartofAccounts):会计科目表是根据公司的业务、报告和其他法定要求定义的账户结构。它决定了如何对会计信息进行采集、分类和存储,从而体现了会计信息的分类和记录方式这一会计假设。在OracleEBS中,会计科......
  • oracle spatial
    oraclespatial播报编辑讨论上传视频用来存储、管理、查询空间数据的功能函数本词条缺少概述图,补充相关内容使词条更完整,还能快速升级,赶紧来编辑吧!OracleSpatial是一个用来存储、管理、查询空间数据的功能函数。提供了一套SQL方案和函数,用来存储、检索、更新和查询......
  • 数据库运维实操优质文章文档分享(含Oracle、MySQL等) | 2024年9月刊
    本文为大家整理了墨天轮数据社区2024年9月发布的优质技术文章/文档,主题涵盖Oracle、MySQL、PostgreSQL等主流数据库系统以及国产数据库的技术实操,从基础的安装配置到复杂的故障排查,再到性能优化的实用技巧及常用脚本等,分享给大家:Oracle优质技术文章概念梳理&安装配置Oracle授......
  • TF卡长期不用会丢失数据吗?TF卡数据恢复容易吗?
    在现代科技快速发展的时代,TF卡(TransFlash卡)作为便携式存储设备,广泛应用于手机、相机、无人机等多种电子设备中,成为我们日常存储照片、视频、文档等重要数据的得力助手。然而,关于TF卡长期不使用是否会丢失数据,以及TF卡数据恢复难易程度的问题,一直是用户关注的焦点。本文将从这两......
  • ORACLE 添加自定义函数
    返回一个值createorreplaceFUNCTIONGET_KEY_BY_QUERY(AAAINVARCHAR2)RETURNNUMBERISITEM_VALUENUMBER;BEGINSELECT'TEST'INTOITEM_VALUEFROMDUAL;RETURNITEM_VALUE;END;返回结果集CREATEORREPLACEFUNCTIONGET_LIST_BY_QUERY(......
  • ORACLE 自定义函数,把字符串拆分为列/结果集
    使用REGEXP_SUBSTRSELECTREGEXP_SUBSTR(key,'[^,]+',1,ROWNUM)ASVALUEFROM(select'1,3,4,4'askeyfromdual)CONNECTBYROWNUM<=LENGTH(key)-LENGTH(REPLACE(key,',',''))+1;自定义函数:ODCIVARCHAR2LI......