如何获取oracle中的数据修改历史记录

如何获取oracle中的数据修改历史记录,第1张

需要用update语句来进行修改。

update语句基本语法:

1

update 表名 set 字段='值' where 条件;

如test表中有如下数据

现在要将ID=3的这条数据的NAME改成badkano,可用如下语句:

1

2

update test set NAME='badkano' where ID=3;

commit;

运行后的结果:

说明:

update语句执行后,必须commit来提交,否则只在当前session中有效。

根据oracle数据库的特点和提供的工具,主要方法有以下几种方法:

利用逻辑备份使用import工具丢失数据的表

利用物理备份来通过还原数据文件并进行不完全恢复

利用dbms_logmnr包从redo log文件中恢复

利用flashback特性恢复数据

前提

为了方便使用方法的介绍,上述恢复方法都将基于以下场景进行:系统管理员在前一天晚上11点用export对数据库做了全库逻辑备份,然后对所有数据文件进行了热备份。第二天上午10点,系统管理员在修改表TFUNDASSET的数据时,由于修改语句的条件写错了,导致一批记录(几千条)的ztm字段被修改成了错误的值,而且已经提交。这个表是资产表,相对而言数据变化不频繁。

一、利用逻辑备份使用import工具恢复丢失的数据

export/import是oracle提供的用于对数据库进行逻辑备份的工具。该工具适用于备份那些数据量不大、业务量不多的数据库系统。因为如果在前一天晚上11点用export做了逻辑备份,那么当今天上午10点数据库意外崩溃时,从备份起到数据库崩溃的这段时间里的数据修改 *** 作(包括DDL和DML)都会丢失。如果丢失数据内的表上的数据是相对比较稳定,也就是说该表上基本没有DML *** 作,例如标准代码表、分区表里的历史数据,那么采用import来导入该表可以比较完整的恢复数据。如果该表是经常变化的业务表,那么这些丢失的数据只能根据业务情况从纸质记录恢复,或者其他途径恢复。

▲示例如下:这个表是一个资产表。相对来说,今天系统运行中修改的数据较少,丢失的数据量可以承受或者可以从别的途径恢复。那就可以用import来恢复。

方法一:

1、把这个表的数据备份到另一个表:

8bef9890242e5d20d09563896cef1471png

2、删除该表的记录:

625dfa5d5986ca5c37dd5017953407cbpng

3、执行下面的命令:

3754d50cc473bd44236d927f00196d24png

这个命令中在关键字tables中指定需要导入的表名字,ignore=y表示忽略表已经存在的错误。

4、导入结束后,检查表中的记录,并用适当的方法恢复当天的修改。

方法二:

1、 把需要恢复的表导入到另一个用户下面:

33806d1216df5ae9c45890d3d45930eepng

2、检查数据以后,把原表记录删除:

fe23a8a4602702e951e5ab48a7460e3bpng

3、然后从另一用户表中插入回去:

729976810ef459046df40b791a6ca773png

4、 数据量比较大时可以采用如下方法:

e377d10ff07132f160185cb1ba119cfcpng

二、利用物理备份来通过还原数据文件并进行不完全恢复

如果数据库运行在归档模式下,那么可以通过使用以前的数据文件备份进行还原,然后利用归档日志进行前滚,直到回滚到错误 *** 作的时间点前,然后重置日志文件打开数据库。

可以通过下列方法确认是否是运行在归档模式:

c8406e42aef7ccc8ef232cfdd535e825png

如果是如上所示,那么就是运行在归档模式了。

▲假定在前一天晚上11点做了全库物理备份,那么可以考虑如下恢复:

1、关闭数据库:

由于数据库的不完全恢复必须在一个关闭的数据库上实施,利用一个旧的数据库的备份还原,然后用日志根据需要逐步前滚,而不能还原一个新的备份,再回退到某个时间点。

通知各客户端数据库将关闭,然后发出:

401f68e89cbfa03388f5913bf5f1ecfdpng

数据库已经关闭。

已经卸载数据库。

ORACLE 例程已经关闭。

2、确定错误 *** 作的时间:

可以根据 *** 作员的估计来确定不完全恢复需要前滚停止的时间,也可以利用LogMiner来分析日志文件(这个工具将在后面介绍),找出错误 *** 作的准确时间。

3、还原数据文件:

先对当前的数据库文件进行备份,然后再用以前的最近一次备份覆盖现有数据文件。注意:不覆盖现有的控制文件。

4、基于时间点恢复,启动数据库到装配状态:

8802043c250eb2a060285be160f48c36png

这样数据库就恢复到了2015年10月20日的9点58分零秒。

然后再利用业务资料补充这段时间内的数据。

三、利用dbms_logmnr包从log文件中恢复

这个包是由Oracle提供,与dbms_logmnr_d包配合使用可以方便地分析联机日志文件和归档日志文件,从这些日志文件中提取出所有对数据库的更改 *** 作。

在使用这个包之前,需要先做一些设置和修改:

1、打开initorclora,修改初始化参数utl_file_dir,设置dbms_logmnr_d包将要使用的数据字典文件的放置目录。

eb6dad504d6f5841641cbd02c5f6dee1png

然后重启数据库使参数生效。

2、以sys用户连接到数据库执行dbmslmdsql脚本重建dbms_logmnr_d这个包。

应用Logminer分析重做日志文件的 *** 作主要有以下步骤:

● 使用dbms_logmnr_d里的存储过程build创建一个外部数据字典文件;

● 使用dbms_logmnr里的存储过程add_logfile添加要分析的日志文件;

● 使用dbms_logmnr里的存储过程start_logmnr启动分析;

● 查询与dbms_logmnr相关的几个视图来获取日志文件内容;

● 使用dbms_logmnr里的存储过程end_logmnr结束分析。

▲下面详细讲述使用的过程

1、使用dbms_logmnr_d里的存储过程build创建一个外部数据字典文件:

a0975e25f5049f1ffdfdd49ad7ae943dpng

2、使用dbms_logmnr里的存储过程add_logfile添加要分析的日志文件到待分析文件列表:

d16ea343204a3a15b29bc6b94985d48dpng

如果没有运行在归档模式,那么由于重做日志文件的循环使用可能导致日志文件被覆盖而无法获取到所要寻找的恢复条目。如果运行在归档模式,则可以通过查看$ORACLE_HOMEadminorclbdump目录下的alert_orcllog里日志文件归档的时间和错误 *** 作的时间来确定加入哪些归档日志文件到待分析的文件列表中去。

eff89b61175131d3edda456d8d9bc18epng

注意:执行以上过程时logfilename参数需要写日志文件的全路径,否则会报错。重复以上 *** 作直到把所有需要分析的文件都加到列表中去。这样就可以启动进行分析。

3、使用dbms_logmnr里的存储过程start_logmnr启动分析;

3630359ea5afa57b5ea51c89da5b8c41png

这样就可以通过下面的查询来获取日志文件的内容了。

4、查询与dbms_logmnr相关的几个视图来获取日志文件内容;

3f8098efdbe50d4b5b4a5311eab6b5d0png

这样就可以找出要恢复所需的语句。注意:v$logmnr_contents只对执行dbms_logmnrstart_logmnr的会话有效,如果通过其他会话或者使用dbms_logmnrend_logmnr终止了分析,都将不能访问v$logmnr_contents的数据。如果要使其他会话也能获取到这些数据,可以通过另外建表来实现,如:

create table undo_sql as select from v$logmnr_contents。

再对undo_sql进行授权,其他用户就可以访问v$logmnr_contents的数据了。

5、使用dbms_logmnr里的存储过程end_logmnr结束分析。

使用完成以后用下面的命令来结束分析活动:exec dbms_logmnrend_logmnr;

这样就释放了分配给logminer的资源(内存和数据结构)。

从上面的过程可知,如果是更新的数据量比较大,而日志文件比较小,就可能会导致日志文件的切换。如果没有及时去挖掘日志文件(没有运行在归档模式),那么可能会由于日志文件的循环使用而导致数据不可恢复。如果运行在归档模式,也可能由于需要分析的日志文件比较多而时间较长。

四、利用flashback新特性恢复数据

Oracle9i 开始提供了闪回查询(Flashback Query)功能,对于误删除或者误更新并且已经commit了的情况提供了简便快捷的恢复方法;而在Oracle 提供闪回查询之前,碰到这种情况只能通过备份来进行基于时间点的恢复或者使用logmnr挖掘日志来恢复,无疑这比闪回查询要麻烦而且费时。

使用这个Flashback Query特性的前提条件:

1 数据库必须处于Automatic Undo Management 状态。

9d9facd0a8d3e8675284d38f601525d1png

2 最大可以闪回查询的时间段由UNDO_RETENTION 初始化参数(单位为秒)指定

b7a419e2f47bd4d31005ca2d9b4a7c58png

可以通过ALTER SYSTEM SET UNDO_RETENTION = ;来动态修改参数值。

▲如何使用Flashback Query来恢复数据呢?

1 通过SQL

28b1053a806762ec87261e80f0e8751fpng

使用SELECT 语句的AS OF 来进行闪回查询,语法如下:

使用AS OF 关键字来对表,视图或者物化视图进行Flashback Query,如果指定了SCN,那么expr 部分必须是一个数字,如果指定了TIMESTAMP,那么expr 必须是一个timestamp类型的值。查询结果将返回在指定的SCN 或者时间点上的数据。

下面我们使用scott 方案来作一个实验。

24547dbf2f8f3515319435d98acc0f10png

如果想在update 的子查询部分使用AS OF,那么该查询只能返回一条记录,否则将会报错。

可以通过添加一个临时表作为中转,然后再作更新,如下:

5605ae591ab357c7148787937df03e17png

2.通过DBMS_FLASHBACK包来恢复

DBMS_FLASHBACK 包提供了以下几个函数:

ENABLE_AT_TIME:设置当前SESSION 的闪回查询时间

ENABLE_AT_SYSTEM_CHANGE_NUMBER:设置当前SESSION 的闪回查询SCN

GET_SYSTEM_CHANGE_NUMBER:取得当前数据库的SCN

DISABLE:关闭当前SESSION 的闪回查询

当将一个SESSION 设置为闪回查询模式之后,后续的查询都会基于那个时间点或者SCN 的数据库状态,如果SESSION 结束,那么即使没有明确指定DISABLE,闪回查询也会自动失效。

当SESSION 运行在闪回查询状态时,不允许进行任何DML 和DDL *** 作。如果要用DML *** 作来进行数据恢复就必须使用PL/SQL 游标。

▲示例:

fbaf8acfe357d8f21039d588c8b658dfpng

通过上面的例子可以看出,只要这个修改的时间不早于sysdate- (UNDO_RETENTION指定的秒数),就可通过这种方式来恢复数据。

e93c4d7b11cf4e7c8ed9a0d27c79ea80png

对于问题中的批量数据,可以写个过程来完成获取到更改前的数据:

然后再用这个临时表里的数据来更新TFUNDASSET就可以了。

五、总结

比较以上几种恢复数据的方法的使用过程,我们可以看出:

● exp/imp只适合于数据变化不大的表的数据丢失的情况,即使用这种方法处理后也需要从业务办理资料中修正数据,否则导致数据丢失;

● 采用基于时间点的不完全恢复可以恢复丢失的数据,但是需要关关闭数据库,减少系统可用时间,而且也会丢失恢复时间点以后的数据;

● 使用LogMiner可以较好的恢复数据,但是要求数据库尽可能运行在归档模式,否则也可能导致数据丢失。好处是不用关闭系统,能够从日志文件中得到所有的数据。

● 使用Flashback最方便和简洁,可以直接得到修改前的数据,但是需要依赖系统设置,并且需要占用大量的回滚表空间。

因此选择什么样的方法来恢复数据,取决于你的系统环境和具体情况,不能生搬硬套。采用正确的方法才能最大程度的减少数据的丢失。

当然,最好是不需要用到这些恢复的办法。前提是,你必须做好以下的工作:

1、 为不同环境创建不同的数据库用户、不同密码(如果不能用户不同,一定要密码不同);

2、 将owner和应用用户分开,并做适度授权;

3、 在做DML前,先用同样的条件做查询,看根据结果集是否符合预期。

可以用dbms_logmnr 它是oracle新提供的一个安装包

1:介绍:dbms_logmnr是oracle在oracle8i所提供的新package。它主要用于分析log file文件(包括online redo log file,archived log file),将log file中的信息转存到v$logmnr_contents中,从而获取对oracle数据库 *** 作的历史信息。它不仅可以分析oracle8i的log file,也可以分析oracle8的log file。信息主要包括在你分析的时间限制内数据库数据作了些什么变更,执行了哪些语句。

2:使用方法

1)打开initora文件,加入utl_file_dir=d:\oracle(注:改为自己的路径,是logminer使用文件的默认路径),然后应用新的设置打开oracle数据库。

2)执行SQL>。 execute dbms_logmnr_dbuild('shwdictora','D:\oracle'); ,(注:将生成d:\oracle\shwdictora文件,此文件可以以后重复使用,但不能同时用于几个logmnr)用于生成数据字典;如果没有dbms_logmnr_d包,需手工执行@d:\oracle\ora8\rdbms\admin\dbmslmdsql;如果执行过程中报下标越界错误,则需要打开@d:\oracle\ora8\rdbms\admin\dbmslmdsql文件,将其中的TYPE col_desc_array IS VARRAY(513) OF col_description的513加大,我是改成了1513,保存文件重新执行@d:\oracle\ora8\rdbms\admin\dbmslmdsql;(注:都要以sysdba身份登陆执行)。

3)将要分析的日志文件加入要分析的log list中,察看有哪些日志文件可以用

select from v$logfile;

查询已经加入那些可以用

select from v$logmnr_logs(注:查询必须在同一个会话中查询,单独开查询将查不到)

语句如下:

execute dbms_logmnradd_logfile('d:\oracle\oradata\shw\redo01_1log',dbms_logmnrnew);

execute dbms_logmnradd_logfile('d:\ORACLE\ORADATA\ORA\REDO02_1LOG',dbms_logmnraddfile);

execute dbms_logmnradd_logfile('d:\ORACLE\ORADATA\ORA\REDO03_1LOG',dbms_logmnraddfile);

如果需要从分析列表里去掉一个文件用

('d:\ORACLE\ORADATA\ORA\REDO03_1LOG',dbms_logmnrremovefile);

4)更改会话时间表达方式(注一定要在本会话下修改,我开始发生错误就是因为在别的会话里修改的,如果允许,可以将数据库默认的时间表达方式修改掉)会话内修改为alter session set nls_date_format='yyyy-mm-dd hh24:mi:ss'; 系统设置在注册表。

5)查询分析的日志文件包含的scn范围和日期范围。

select low_time,high_time,low_scn,next_scn from v$logmnr_logs;会列出你加入的日志文件的以上信息。

6)执行分析:

dbms_logmnrstart_logmnr(

dictfilename => 'd:\oracle\shwdictora',startscn=>xxxxxx,endscn=>xxxxx,starttime => to_date('20030501 12:15:00','yyyymmdd hh24:mi:ss'), endtime => to_date('20030501 15:40:30','yyyymmdd hh24:mi:ss'));

要注意scn范围和日期格式,格式要与你修改的一样。

7:查询

Select SCN,timestamp, session# session_num, sql_redo

From V$LOGMNR_CONTENTS

Order by 1

具体要查询什么内容可以自己修改。

新增archives 时的状况:

条件和假设:自上次镜像备份以来已经生成新的archive log(s); Archivelog Mode; 有同步的datafile(s) 和control file(s) 的镜像(冷)拷贝;archive log(s) 可用。

恢复步骤:

1 如果数据库尚未关闭,则首先把它关闭: $ svrmgrl svrmgrl> connect internal

svrmgrl> shutdown abort

2 将备份文件抄送回原始地点: 所有Database Files

所有Control Files(没有archive(s) 或redo(s) 的情况下,control files 的更新无任何意义)

所有On-Line Redo Logs (Not archives) initora file(选项)

3 启动数据库: $ svrmgrl

svrmgrl> connect internal

svrmgrl> startup

数据文件, 重作日志和控制文件同时丢失或损坏:

条件和假设:Archivelog Mode; 有同步的所有所失文件的镜像(冷)拷贝;archive log(s) 可用

恢复步骤(必须采用不完全恢复的手法):

1 如果数据库尚未关闭,则首先把它关闭: $ svrmgrl svrmgrl> connect internal

svrmgrl> shutdown abort

2 将备份文件抄送回原始地点:

所有Database Files

所有Control Files

所有On-Line Redo Logs(Not archives)

initora file(选项)

3 启动数据库然而并不打开:

svrmgrl>startup mount

4 做不完全数据库恢复,应用所有从上次镜像(冷)备份始积累起来的archives:

svrmgrl> recover database until cancel using backup controlfile;

cancel

5 Reset the logfiles (对启动而言不可省略):

svrmgrl> alter database open resetlogs;

6 关闭数据库并做一次全库冷备份。

数据文件和控制文件同时丢失或损坏:

条件和假设:Archivelog Mode; 有同步的datafile(s) 和control file(s) 的冷拷贝;archive log(s) 可用

恢复步骤:

1 将冷拷贝的datafiles(s) 和control file(s) 抄送回原始地点:

$ cp /backup/good_onedbf /orig_loc/bad_onedbf

$ cp /backup/control1ctl /disk1/control1ctl

2 以mount 选项启动数据库:

$ svrmgrl

svrmgrl> connect internal

svrmgrl> startup mount

3 以旧的control file 来恢复数据库:

svrmgrl> recover database until cancel using backup controlfile;

介质恢复完成

(须在应用完最后一个archive log 后cancel )

4 Reset the logfiles (对启动而言不可省略):

svrmgrl> alter database open resetlogs;

重作日志和控制文件同时丢失或损坏时:

条件和假设:Control Files 全部丢失或损坏;Archivelog Mode; 有Control Files 的镜像(冷)拷贝

恢复步骤:

1 如果数据库尚未关闭,则首先把它关闭:

$ svrmgrl

svrmgrl> connect internal

svrmgrl> shutdown abort

svrmgrl>exit

2 以Control File 的镜像(冷)拷贝覆盖损坏了的Control File:

$ cp /backup/control1ctl /disk1/control1ctl

3 启动数据库然而并不打开:

$ svrmgrl

svrmgrl> connect internal

svrmgrl> startup mount

4 Drop 坏掉的redo log (排除硬件故障):

svrmgrl> alter database drop logfile group 2;

5 重新创建redo log:

svrmgrl> alter database add logfile group 2 '/orig_loc/log2dbf' size 10M;

6 以旧的control file 来恢复数据库:

svrmgrl> recover database until cancel using backup controlfile;

(必须马上cancel )

7 Reset the logfiles (对启动而言不可省略):

svrmgrl> alter database open resetlogs;

8 关闭数据库并做一次全库冷备份

只发生归档重作日志丢失或损坏时:

根据不同环境和情况,选择下述手段之一:

a 马上backup 全部datafiles (如果系统采用一般热备份或RMAN 热备份)

b 马上正常关闭数据库并进行冷备份(如果系统采用冷备份)

c 冒险前进!不做备份而让数据库接着跑,直等到下一个备份周期再做备份。这是在赌数据库在下一个备份周期到来之前不会有需要恢复的错误发生。

注意:冒险前进的选择:如果发生错误而需要数据库恢复,则最多只能恢复到出问题archive log 之前的 *** 作现场。从另一个角度讲,archive log(s) 出现问题时,数据库若不需要恢复则其本身并没有任何问题。

Oracle逻辑结构故障的处理方法:

逻辑结构的故障一般指由于人为的误 *** 作而导致重要数据丢失的情况。在这种情况下数据库物理结构是完整的也是一致的。对于这种情况采取对原来数据库的全恢复是不合适的,我们一般采用三种方法来恢复用户数据。

采用exp/imp工具来恢复用户数据:

如果丢失的数据存在一个以前用exp命令的备份,则可以才用这种方式。

1 在数据库内创建一个临时用户:

svrmgrl>create user test_user identified by test;

svrmgrl>grant connect,resource to test_user;

2 从以前exp命令备份的文件中把丢失数据的表按照用户方式倒入测试用户:

$imp system/manager file=export_file_name tables=(lost_data_table_name…) fromuser=lost_data_table_owner touser=test_user constraint=n;

3 用相应的DML语句将丢失的数据从测试用户恢复到原用户。

4 将测试用户删除:

svrmgrl>drop user test_user cascede;

采用logminer来恢复用户数据:

Logminer是oracle提供的一个日志分析工具。它可以根据数据字典对在线联机日志、归档日志进行分析,从而可以获得数据库的各种DML *** 作的历史记录以及各种DML *** 作的回退信息。根据这些用户就可以将由于误 *** 作而丢失的数据重新加入数据库内。

1 确认数据库的utl_file_dir参数已经设置,如果没有则需要把这个参数加入oracle的初始化参数文件,然后重新启动数据库。下面例子中假设utl_file_dir=’/opt/oracle/db01’;

2 创建logminer所需要的数据字典信息,假设生成的数据字典文本文件为dictora:

svrmgrl>execute dbms_logmnr_dbuild(dictionary_filename=>'dictora', dictionary_location=>'/opt/oracle/db01’);

3 确定所需要分析的日志或者归档日志的范围。这可以根据用户误 *** 作的时间来确定大概的日志范围。假设用户误 *** 作时可能的日志文件为/opt/oracle/db02/oradata/ORCL/redo3log和归档日志’/opt/oracle/arch/orcl/orclarc_1_113ora’。

4 创建要分析的日志文件列表,按日志文件的先后顺序依次加入:

svrmgrl>execute dbms_logmnradd_logfile(logfilename=>’/opt/oracle/arch/orcl/orclarc_1_113ora’,options=>dbms_logmnrNEW);

svrmgrl> execute dbms_logmnradd_logfile(logfilename=>’ /opt/oracle/db02/oradata/ORCL/redo3log’,options=>dbms_logmnrADDFILE);

5 开始日志分析,假设需要分析的时间在’2003-06-28 12:00:00’和’2003-06-28 13:00:00’之间:

svrmgrl>execute dbms_logmnrstart_logmnr(dictfilename=>’ /opt/oracle/db01/dictora’,starttime=>to_date(’ 2003-06-28 12:00:00’,’YYYY-MM-DD HH:MI:SS’),endtime=>to_date(to_date(‘2003-06-28 13:00:00’,’YYYY-MM-DD HH:MI:SS’));

6 获取分析结果:

svrmgrl>select operation,sql_redo,sql_undo from v$logmnr_contents;

7 根据分析结果修复数据。

8结束logmnr:

svrmgrl>dbms_logmnrend_logmnr;

9 用适当的方法对原数据库进行数据库全备份。

利用备份恢复用户数据:

采用这种方法时并不是在原数据库进行恢复,而是利用数据库备份在新的机器上重新建立一个新的数据库。通过备份恢复在新机器上将数据库恢复到用户误 *** 作前,这样就可以获得丢失的数据将其恢复到原数据库。

1 在新的机器上安装数据库软件。

2 对于采用带库备份的现场,需要在新的数据库服务器上安装调试相应的备份管软件。

3 根据用户误 *** 作的时间点进行基于时间点的数据库恢复 *** 作。对于没有采用带库备份的现场,可以选取用户误 *** 作前最近的备份磁带进行恢复;对于才用带库备份的点可以通过基于时间恢复点恢复的rman脚本来进行恢复。

4重新打开数据库:

svrmgrl>alter database open resetlogs;

5 从新的数据库中获取丢失的用户数据,通过DML *** 作将其恢复到原数据库中。

6 用适当的方法对原数据库进行数据库全备份。

以上就是关于如何获取oracle中的数据修改历史记录全部的内容,包括:如何获取oracle中的数据修改历史记录、oracle存储过程失效重启后恢复正常、请问oracle的archive log用什么软件能读等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/web/9380594.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-04-27
下一篇 2023-04-27

发表评论

登录后才能评论

评论列表(0条)

保存