oracle存储过程失效重启后恢复正常

oracle存储过程失效重启后恢复正常,第1张

根据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、把这个表的数据备份到另一个表:

8bef9890242e5d20d09563896cef1471.png

2、删除该表的记录:

625dfa5d5986ca5c37dd5017953407cb.png

3、执行下面的命令:

3754d50cc473bd44236d927f00196d24.png

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

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

方法二:

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

33806d1216df5ae9c45890d3d45930ee.png

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

fe23a8a4602702e951e5ab48a7460e3b.png

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

729976810ef459046df40b791a6ca773.png

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

e377d10ff07132f160185cb1ba119cfc.png

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

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

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

c8406e42aef7ccc8ef232cfdd535e825.png

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

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

1、关闭数据库:

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

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

401f68e89cbfa03388f5913bf5f1ecfd.png

数据库已经关闭。

已经卸载数据库。

ORACLE 例程已经关闭。

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

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

3、还原数据文件:

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

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

8802043c250eb2a060285be160f48c36.png

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

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

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

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

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

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

eb6dad504d6f5841641cbd02c5f6dee1.png

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

2、以sys用户连接到数据库执行dbmslmd.sql脚本重建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创建一个外部数据字典文件:

a0975e25f5049f1ffdfdd49ad7ae943d.png

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

d16ea343204a3a15b29bc6b94985d48d.png

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

eff89b61175131d3edda456d8d9bc18e.png

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

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

3630359ea5afa57b5ea51c89da5b8c41.png

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

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

3f8098efdbe50d4b5b4a5311eab6b5d0.png

这样就可以找出要恢复所需的语句。注意:v$logmnr_contents只对执行dbms_logmnr.start_logmnr的会话有效,如果通过其他会话或者使用dbms_logmnr.end_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_logmnr.end_logmnr

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

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

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

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

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

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

9d9facd0a8d3e8675284d38f601525d1.png

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

b7a419e2f47bd4d31005ca2d9b4a7c58.png

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

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

1. 通过SQL

28b1053a806762ec87261e80f0e8751f.png

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

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

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

24547dbf2f8f3515319435d98acc0f10.png

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

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

5605ae591ab357c7148787937df03e17.png

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 游标。

▲示例:

fbaf8acfe357d8f21039d588c8b658df.png

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

e93c4d7b11cf4e7c8ed9a0d27c79ea80.png

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

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

五、总结

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

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

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

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

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

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

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

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

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

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

删除表后,可以采用如下 *** 作:

在 user_recyclebin中找到最近 *** 作过的表名称,然后用闪回(只能用于10G及以上版本)。

FLASH BACK TABLE TABLE_NAME TO BEFORE DROP

如果是删了或修改里面的数据,可以先建立一个快表将删除修改之前状态的数据找回到这个表中:

CREATE TABLE QUICK_TABLE AS

SELECT * FROM TABLE_NAME AS OF TIMESTAMP SYSTEM-1/24 (一小时前的),减去的时间可以自己定。如楼上F_253那位老兄的写法就不错,能自由定制时间

1、安装 *** 作系统

2、安装数据库系统

3、安装nbu软件及配置

--安装客户端

上传SYMCnbclient_Linux-RedHat2.6.18_7.5.0.2.tar编辑本机hosts

vi /etc/hosts

添加:192.168.99.252 hdnbu1

解压:

[root@scmtest u01]# tar -xvf SYMCnbclient_Linux-RedHat2.6.18_7.5.0.2.tar[root@scmtest u01]# cd SYMCnbclient_Linux-RedHat2.6.18_7.5.0.2[root@scmtest SYMCnbclient_Linux-RedHat2.6.18_7.5.0.2]# ./install过程当中要输入备份服务端:hdnbu1

然后再用oracle用户执行:

[root@scmtest bin]# su - oracle

[oracle@scmtest ~]$ cd /usr/openv/netbackup/bin[oracle@scmtest bin]$ ./oracle_link

Thu Feb 21 14:03:02 CST 2013

All Oracle instances should be shutdown before running this script.

Please log into the Unix system as the Oracle owner for running this scriptDo you want to continue? (y/n) [n] y

LIBOBK path: /usr/openv/netbackup/bin

ORACLE_HOME: /software/oracle/product/10.2.0/db1Oracle version: 10.2.0.5.0

Platform type: x86_64

Linking LIBOBK:

ln -s /usr/openv/netbackup/bin/libobk.so64 /software/oracle/product/10.2.0/db1/lib/libobk.soDone

Please check the trace file located in /tmp/make_trace.23602to make sure the linking process was successful.

4、编辑初始参数文件

这时候,需要进行修改,比如原来用的什么盘,现在用什么盘等编辑后如下:

*._addm_auto_enable=FALSE

*._b_tree_bitmap_plans=FALSE

*._db_block_numa=1

*._enable_NUMA_optimization=FALSE

*._optimizer_cartesian_enabled=FALSE

*._optimizer_skip_scan_enabled=FALSE

*.archive_lag_target=1800

*.audit_file_dest='/software/oracle/admin/ncerp/adump'

*.background_dump_dest='/software/oracle/admin/ncerp/bdump'

*.compatible='10.2.0.5.0'

*.control_files='/u01/ncerp/control/control01.ctl','/u01/ncerp/control/control02.ctl'

*.core_dump_dest='/software/oracle/admin/ncerp/cdump'

*.db_block_size=8192

*.db_cache_size=4294967296

*.db_create_file_dest='/u01/ncerp/flash_recover'

*.db_domain=''

*.db_file_multiblock_read_count=16

*.db_name='ncerp'

*.java_pool_size=33554432

*.job_queue_processes=10

*.large_pool_size=33554432

*.log_archive_dest_1='location=/u01/ncerp/arch'

*.log_archive_format='%s_%t_%r.log'

*.max_dump_file_size='1024'

*.open_cursors=1000

*.optimizer_dynamic_sampling=4

*.optimizer_index_cost_adj=40

*.parallel_max_servers=5

*.pga_aggregate_target=2147483648

*.processes=800

*.recyclebin='OFF'

*.shared_pool_size=838860800

*.undo_management='AUTO'

*.undo_tablespace='UNDOTBS1'

5、根据参数文件,建相应的目录

[oracle@scmtest ~]$ mkdir -p /u01/ncerp/control/[oracle@scmtest u01]$ mkdir -p /app/oracle/admin/ncerp/cdump[oracle@scmtest u01]$ mkdir -p /app/oracle/admin/ncerp/bdump[oracle@scmtest u01]$ mkdir -p /app/oracle/admin/ncerp/adump[oracle@scmtest u01]$ mkdir -p /app/oracle/admin/ncerp/pfile[oracle@scmtest u01]$ mkdir -p /u01/ncerp/flash_recover[oracle@scmtest u01]$ mkdir -p /u01/ncerp/arch[oracle@scmtest ncerp]$ mkdir oradata

注意:这些要与参数文件对应,要不然无法启动!

6、恢复控制文件

export ORACLE_SID=ncerp

[oracle@scmtest u01]$ rman target /

Recovery Manager: Release 10.2.0.5.0 - Production on Thu Feb 21 14:17:10 2013Copyright (c) 1982, 2007, Oracle. All rights reserved.

connected to target database (not started)RMAN>startup nomount pfile='/u01/ncpfile.ora'Oracle instance started

Total System Global Area5217714176 bytesFixed Size 2103536 bytesVariable Size905971472 bytesDatabase Buffers4294967296 bytesRedo Buffers 14671872 bytes从nbu的服务器上查询要恢复的控制文件

hdnbu1:/tmp # bplist -C RD162 -t 4 -R -b -l / | more-rw-rw---- oracledba 10747904 Mar 28 11:26 /c-3383507379-20130328-0b-rw-rw---- oracledba 11010048 Mar 28 11:25 /c-2177845250-20130328-0d-rw-rw---- oracledba 10747904 Mar 28 11:25 /cntrl_9202_1_811250475-rw-rw---- oracledba 10747904 Mar 28 11:25 /cntrl_7788_1_811250456-rw-rw---- oracledba 10747904 Mar 28 11:25 /c-3383507379-20130328-0a-rw-rw---- oracledba 11010048 Mar 28 11:24 /c-2177845250-20130328-0c-rw-rw---- oracledba 114032640 Mar 28 11:17 /al_7786_1_811249961-rw-rw---- oracledba 123207680 Mar 28 11:17 /al_7785_1_811249961-rw-rw---- oracledba 3670016 Mar 28 11:17 /al_9200_1_811249960-rw-rw---- oracledba 3932160 Mar 28 11:17 /al_9199_1_811249959-rw-rw---- oracledba 11010048 Mar 28 09:25 /c-2177845250-20130328-0b-rw-rw---- oracledba 10747904 Mar 28 09:25 /c-3383507379-20130328-09-rw-rw---- oracledba 10747904 Mar 28 09:25 /cntrl_9197_1_811243259-rw-rw---- oracledba 10747904 Mar 28 09:25 /cntrl_7783_1_811243253RMAN>run

2>{

3>allocate channel c1 type 'sbt_tape'

4>send 'NB_ORA_CLIENT=RD162'

5>restore controlfile from '/cntrl_24145_1_828414748'6>release channel c1

7>}

using target database control file instead of recovery catalogallocated channel: c1

channel c1: sid=874 devtype=SBT_TAPE

channel c1: Veritas NetBackup for Oracle - Release 7.5 (2012050902)sent command to channel: c1

Starting restore at 2013-03-28 12:41:30

channel c1: restoring control file

channel c1: restore complete, elapsed time: 00:05:16output filename=/u02/ncerp/control/control01.ctloutput filename=/u02/ncerp/control/control02.ctlFinished restore at 2013-03-28 12:46:47

released channel: c1

7、还原数据库文件

在这里要查一下数据库是否已经mount

SQL>select status from v$instance

STATUS

------------

MOUNTED

RMAN>run {

ALLOCATE CHANNEL ch00 TYPE 'SBT_TAPE'

send 'NB_ORA_CLIENT=RD162'

set newname for datafile '/backup/ncerp/oradata/system01.dbf' to '/u02/ncerp/oradata/system01.dbf' set newname for datafile '/backup/ncerp/oradata/system02.dbf' to '/u02/ncerp/oradata/system02.dbf' set newname for datafile '/backup/ncerp/oradata/nnc_index03_1.dbf' to '/u02/ncerp/oradata/nnc_index03_1.dbf'set newname for datafile '/backup/ncerp/oradata/undotbs1.dbf' to '/u02/ncerp/oradata/undotbs1.dbf' set newname for datafile '/backup/ncerp/oradata/sysaux01.dbf' to '/u02/ncerp/oradata/sysaux01.dbf' set newname for datafile '/backup/ncerp/oradata/users01.dbf' to '/u02/ncerp/oradata/users01.dbf' set newname for datafile '/backup/ncerp/oradata/nnc_data01_1.dbf' to '/u02/ncerp/oradata/nnc_data01_1.dbf' set newname for datafile '/backup/ncerp/oradata/nnc_data01_2.dbf' to '/u02/ncerp/oradata/nnc_data01_2.dbf' set newname for datafile '/backup/ncerp/oradata/nnc_data01_3.dbf' to '/u02/ncerp/oradata/nnc_data01_3.dbf' set newname for datafile '/backup/ncerp/oradata/nnc_data01_4.dbf' to '/u02/ncerp/oradata/nnc_data01_4.dbf' set newname for datafile '/backup/ncerp/oradata/nnc_data02_1.dbf' to '/u02/ncerp/oradata/nnc_data02_1.dbf' set newname for datafile '/backup/ncerp/oradata/nnc_data02_2.dbf' to '/u02/ncerp/oradata/nnc_data02_2.dbf' set newname for datafile '/backup/ncerp/oradata/nnc_data03_1.dbf' to '/u02/ncerp/oradata/nnc_data03_1.dbf' set newname for datafile '/backup/ncerp/oradata/nnc_data03_2.dbf' to '/u02/ncerp/oradata/nnc_data03_2.dbf' set newname for datafile '/backup/ncerp/oradata/nnc_data03_3.dbf' to '/u02/ncerp/oradata/nnc_data03_3.dbf' set newname for datafile '/backup/ncerp/oradata/nnc_data03_4.dbf' to '/u02/ncerp/oradata/nnc_data03_4.dbf' set newname for datafile '/backup/ncerp/oradata/nnc_index02_1.dbf' to '/u02/ncerp/oradata/nnc_index02_1.dbf'set newname for datafile '/backup/ncerp/oradata/nnc_index01_1.dbf' to '/u02/ncerp/oradata/nnc_index01_1.dbf'set newname for datafile '/backup/ncerp/oradata/nnc_index01_2.dbf' to '/u02/ncerp/oradata/nnc_index01_2.dbf'set newname for datafile '/backup/ncerp/oradata/nnc_index01_3.dbf' to '/u02/ncerp/oradata/nnc_index01_3.dbf'set newname for datafile '/backup/ncerp/oradata/nnc_index01_4.dbf' to '/u02/ncerp/oradata/nnc_index01_4.dbf'set newname for datafile '/backup/ncerp/oradata/iufo01.dbf'to '/u02/ncerp/oradata/iufo01.dbf' set newname for datafile '/backup/ncerp/oradata/iufo02.dbf'to '/u02/ncerp/oradata/iufo02.dbf' set newname for datafile '/backup/ncerp/oradata/nnc_data03_5.dbf' to '/u02/ncerp/oradata/nnc_data03_5.dbf' Restore database

Switch datafile all

}

vi res_test.sh 内容如下:

export ORACLE_SID=ncerp

rman target / <run {

ALLOCATE CHANNEL ch00 TYPE 'SBT_TAPE'

send 'NB_ORA_CLIENT=RD162'

做一次恢复测试看看

说明需要3556这个归档日志

所以恢复时,从这个日志进行恢复!

也可以采用后台运行方式

9、数据库恢复

SQL>

cancel

说明,如果上面日志可能有点大的时候,我们需要调整,比如说删除日志组等,然后还重新添加日志到新位置10、打开数据库

SQL>alter database open resetlogs

Database altered.

11、创建临时表空间


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

原文地址: http://outofmemory.cn/sjk/9934243.html

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

发表评论

登录后才能评论

评论列表(0条)

保存