1) 只有SYSDBA有权执行,闪回前一定要记录当前SCN
2) 需要停机,并要求处于ARCHIVELOG模式中
3) 闪回日志不能被复用和归档,是自动管理的。RVWR进程负责读SGA中的FLASHBACK BUFFER,写闪回日志,写的的内容是完整的数据块映像的日志。
4) 使用FALSHBACK DATABASE闪回后的各数据块SCN很可能不一致,即闪回结果不是一个确定的时间点,而是该时间点前后的一个范围,所以必须用RESETLOGS打开数据库,或者使用alter database open readonly打开查看是否所需(如果在生产环境,read only后就可以EXP重要的表甚至是整个库了),如果是,再RESETLOGS打开,如果不是,shutdown abort后重新闪回。
5) 闪回的结果与不完全恢复一样,闪回点之后的工作都丢失。
6) 不能返回物理讹误,只能返回用户错误导致的逻辑错误。
7) TRUNCATE的表如果选择闪回,只能应用闪回数据库。
8) 闪回数据库将忽略脱机的表空间
SQL> select name,flashback_on from v$database; //查看是否已经启用了闪回,如果启用了就不必重复配置了
NAME FLASHBACK_ON
--------------- ------------------
TEST3 NO
SQL> ARCHIVE LOG LIST;//必须位于ARCHIVEMODE
Database log mode Archive Mode
Automatic archival Enabled
Archive destination USE_DB_RECOVERY_FILE_DEST
Oldest online log sequence 11
Next log sequence to archive 13
Current log sequence 13
(可选)需要重启,如果已经设置可以不必重复设置,设置闪回区的地址,这个存储路径应该是结合硬件的具体情况,因为闪回区如果需要较大空间,或者日后可能做调整,则应该放在一个较大的磁盘分区上或独立磁盘,给日后空间调整留有余地。
SQL>alter system set db_recovery_file_dest='/ss' scope=both;
System altered.
(可选)需要重启,如果已经设置可以不必重复设置,设置闪回区的大小。
SQL>alter system setdb_recovery_file_dest_size=20G scope=both;
System altered.
(可选)需要重启,如果已经设置可以不必重复设置,设置保留时间,1440单位为分钟,即24小时,前提是,闪回区提供了足够的空间,可以存放24小时的内容
SQL>alter system set db_flashback_retention_target=1440 scope=both;
System altered.
SQL>shutdown immediate;
Oracle instance shut down
SQL>startup mount;
connected to target database (not started)
Oracle instance started
Total System Global Area 1272213504 bytes
Fixed Size 1336260 bytes
Variable Size 788532284 bytes
Database Buffers 469762048 bytes
Redo Buffers 12582912 bytes
database mounted
SQL>alter database flashback on;//打开闪回
Database altered.
/**************************************注释************************************************/
SQL>alter tablespace xxx flashback off;//关闭某个表空间的闪回
- 能够容忍长时间停机的表空间可以关闭闪回
- 允许任意删除的表空间可以关闭闪回
- 能够被非常快还原与恢复的表空间可以关闭闪回
- 如果某表空间没有打开闪回,则在闪回数据库之前,必须将此表空间OFFLINE,闪回将忽略脱机的表空间。否则会报ORA-38753和ORA-01110
/**************************************注释结束*********************************************/
SQL>alter database open; //打开数据库
Database altered
1) 查看闪回恢复区及大小是否设置
SQL>showparameter db_recovery;
NAME TYPE VALUE
--------------------------------------- --------------------------
db_recovery_file_dest string /u01/app/oracle/flash_recovery_area
db_recovery_file_dest_size big integer 3852M
2) 查询目前的设置能够最远闪回多久的数据库
SQL> select oldest_flashback_scn as oldest_scn,to_char(oldest_flashback_time,'yyyy-mm-ddhh24:mi:ss') as oldest_time from v$flashback_database_log;
OLDEST_SCNOLDEST_TIME
-----------------------------
837455 2013-07-27 16:50:30
3)
select oldest_flashback_scn as oldest_scn,to_char(oldest_flashback_time,'yyyy-mm-ddhh24:mi:ss') as oldest_time,retention_target,flashback_size/1024/1024 as fb_size_mb,estimated_flashback_size/1024/1024 as estimated_size_mb from v$flashback_database_log;
4) 查找每个时间段内闪回数据库所需的数据
SQL>select to_char(begin_time,'yyyy-mm-dd hh24:mi:ss') as begin_time,to_char(end_time,'yyyy-mm-dd hh24:mi:ss') as end_time,flashback_data/1024/1024 as fb_date_mb,db_data/1024/1024 as db_date_mb,redo_data/1024/1024 as redo_date_mb,estimated_flashback_size as estimated_size from v$flashback_database_stat;
5) SGA 中自动分配的闪回缓冲区
SQL>select * from v$sgastat where name='flashback generation buff';
POOL NAME BYTES
---------------------------------------------------- ----------
shared pool flashback generation buff 8388608
6) 查找具体的表空间是否打开闪回
SQL>select name,flashback_on from v$tablespace;
NAME FLASHBACK_ON
----------------------------------------------------------
SYSTEM YES
SYSAUX YES
UNDOTBS1 YES
USERS YES
TEMP YES
TEST_SPACE YES
READONLY_SPACE YES
OFFLINE_SPACE YES
INDEX_SPACE YES
4.1 SQLPLUS
4.1.1环境模拟
1) 确定当前时间
SQL> select to_char(sysdate,'yyyy-mm-dd hh24:mi:ss') from dual;
TO_CHAR(SYSDATE,'YY
-------------------
2013-07-27 20:56:32
2) 确定当前SCN
SQL> select current_scn from v$database;
CURRENT_SCN
-----------
839748
3) 指定表原始状态
SQL> select * from knight.books;
ID NAME PRICE
------------------------------ ----------
1 LINUX 25.55
2 AIX 50.5
3 NETWORK 125.89
4 JAVA 88.99
5 JQUERY 102.98
4) 插入新数据,这些数据在闪回后应该不存在。
SQL> insert into knight.books values(200,'WEBWORK',299.9);
1 row created.
5) 插入新数据,这些数据在闪回后应该不存在。
SQL> insert into knight.books values(201,'PMP',56.99);
1 row created.
SQL> commit;
Commit complete.
6) 表的新状态。
SQL> select * from knight.books;
ID NAME PRICE
------------------------------ ----------
200 WEBWORK 299.9
201 PMP 56.99
1 LINUX 25.55
2 AIX 50.5
3 NETWORK 125.89
4 JAVA 88.99
5 JQUERY 102.98
7 rows selected.
7) 模拟断电关机
SQL>shutdown abort;
4.1.2 开始闪回数据库
I SQL>startup mount;
II SQL>flashback database to timestamp to_timestamp('2013-07-27 20:56:32','yyyy-MM-dd hh24:mi:ss');//最细粒度为百万分之一秒
Flashback complete.
III SQL>alter database open read only;
查看数据库在该时间点下是否为所需状态,如果不是,更换新的时间点后,重复执行I-III。如果已经为所需状态
IV SQL>startup abort; V SQL>alter database open resetlogs;
4.2 RMAN
在RMAN环境下,针对SQLPLUS中的第3步,可以选择另外三种实现方式
RMAN>flashbackdatabase to time=to_date('2013-07-26 18:00:00','yyyy-mm-dd hh24:mi:ss');//最细粒度为秒 RMAN>flashbackdatabase to scn=3655894; RMAN>flashbackdatabase to sequence=56 thread=1;
闪回点指历史上的时间点。
操作点指执行闪回操作时的时间点,这个时间点理论上晚于闪回点。
经过后边的实验,证明在闪回点是OFFLINE的文件都将在闪回过程中被忽略,并且在之后的打开过程中会用到不安全的隐含参数。所以在执行全库闪回的时候,推荐按照以下步骤进行
5.1 闪回点OFFLINE,操作点OFFLINE
这是很麻烦的情况,闪回结果是数据没有被闪回,状态出现错误,最后要求做全备份
1) 确定当前时间
SQL> select to_char(sysdate,'yyyy-mm-dd hh24:mi:ss') from dual;
TO_CHAR(SYSDATE,'YY
-------------------
2013-07-27 20:56:32
2) 确定当前SCN
SQL> select current_scn from v$database;
CURRENT_SCN
-----------
839748
3)插入另外一个表knight.keyboards新数据
SQL> insert into knight.keyboards values(200,'SANSUMG','MECHINE');
1 row created.
4)插入另外一个表新数据
SQL> insert into knight.keyboards values(201,'SNAKE','MECHINE');
1 row created.
SQL> commit;
Commit complete.
5)新表状态
SQL> select * from knight.keyboards;
ID COMPANY TYPE
------------------------------ --------------------
200 SANSUMG MECHINE
201 SNAKE MECHINE
1 IBM 500.55
2 HP 200.5
3 SONY 1200.5
4 ACER 55.6
5 MICROSOFT 108
6)将表knight.keyboards所在空间OFFLINE
SQL> alter tablespace offline_space offline;
Tablespace altered.
7)检查一下,已经不能访问了
SQL> select * from knight.keyboards;
select * from knight.keyboards
*
ERROR at line1:
ORA-00376: file7 cannot be read at this time
ORA-01110: datafile 7: '/ss/offline_space01.dbf'
8)模拟断电关机
SQL>shutdown abort;
9)启动到mount模式
SQL>startup mount;
10) 开始闪回
SQL>flashback database to timestamp to_timestamp('2013-07-27 20:56:32','yyyy-MM-dd hh24:mi:ss');
Flashback complete.
11)resetlogs打开数据库
SQL>alter database open resetlogs;
Database altered.
12)尝试将表空间online,结果报错了,糟糕的01190
SQL> alter tablespace offline_space online;
altert ablespace offline_space online
*
ERROR at line1:
ORA-01190:control file or data file 7 is from before the last RESETLOGS
ORA-01110: datafile 7: '/ss/offline_space01.dbf'
13)使用隐藏参数设置
SQL> alter system set"_allow_resetlogs_corruption"=TRUE scope=spfile;
System altered.
SQL> ALTER SESSIONSET EVENTS 'IMMEDIATE TRACE NAME ADJUST_SCN LEVEL 1';
Session altered.
14)重启数据库后尝试不完全恢复
SQL> shutdown immediate;
Database closed.
Database dismounted.
ORACLE instance shut down.
SQL> startup mount;
ORACLE instance started.
Total System Global Area 1272213504 bytes
Fixed Size 1336260 bytes
Variable Size 822086716 bytes
Database Buffers 436207616 bytes
Redo Buffers 12582912 bytes
Database mounted.
SQL> recover database until cancel;
Media recovery complete.
SQL> alter database datafile 7 online;
Database altered.
SQL> alter database open resetlogs;
Database altered.
SQL> alter tablespace offline_space online;
Tablespace altered.
SQL> select * from knight.keyboards;
ID COMPANY TYPE
------------------------------ --------------------
200 SANSUMG MECHINE
201 SNAKE MECHINE
1 IBM 500.55
2 HP 200.5
3 SONY 1200.5
4 ACER 55.6
5 MICROSOFT 108
7 rows selected.
从结果可以看出,新加入的记录被保存了,并没有按照被闪回到指定的时间点,由此说明,闪回数据库时是忽略操作点OFFLINE表空间的。但是此时SCN已经很乱了,必须全备数据库。
5.2 闪回点OFFLINE,操作点ONLINE
闪回被很好的执行了,无论是数据还是数据文件的状态都恢复到之前的状态。
1)确定当前时间
SQL> select to_char(sysdate,'yyyy-mm-dd hh24:mi:ss') from dual;
TO_CHAR(SYSDATE,'YY
-------------------
2013-07-2720:56:32
2)确定当前SCN
SQL> select current_scn from v$database;
CURRENT_SCN
-----------
839748
3)插入knight.keyboards新数据
SQL>alter tablespace offline_space online;
Tablespace altered.
4)插入knight.keyboards新数据
SQL> insert into knight.keyboards values(200,'SANSUMG','MECHINE');
1 row created.
5)插入knight.keyboards新数据
SQL> insert into knight.keyboards values(201,'SNAKE','MECHINE');
1 row created.
SQL> commit;
Commit complete.
6) 查看一下表新状态
SQL> select * from knight.keyboards;
ID COMPANY TYPE
------------------------------ --------------------
200 SANSUMG MECHINE
201 SNAKE MECHINE
1 IBM 500.55
2 HP 200.5
3 SONY 1200.5
4 ACER 55.6
5 MICROSOFT 108
7)模拟断电关机
SQL>shutdown abort;
8)启动到mount模式
SQL>startup mount;
9) 开始闪回
SQL>flashback database to timestamp to_timestamp('2013-07-27 20:56:32','yyyy-MM-dd hh24:mi:ss');
Flashback complete.
10)闪回后各数据文件的状态。
SQL> select file#,status from v$datafile;
FILE# STATUS
-----------------
1 SYSTEM
2 RECOVER
3 RECOVER
4 RECOVER
5 RECOVER
6 ONLINE
7 RECOVER
8 RECOVER
8 rows selected.
11)打开前查看一下
SQL> alter database open read only;
Database altered.
12)看到此时新加入的数据已经不存在了。
SQL> select * from knight.keyboards;
ID COMPANY TYPE
------------------------------ --------------------
1 IBM 500.55
2 HP 200.5
3 SONY 1200.5
4 ACER 55.6
5 MICROSOFT 108
13)重新启动并尝试打开数据库
SQL> shutdown abort;
ORACLE instance shut down.
SQL> startup mount;
ORACLE instance started.
Total System Global Area 1272213504 bytes
Fixed Size 1336260 bytes
Variable Size 822086716 bytes
Database Buffers 436207616 bytes
Redo Buffers 12582912 bytes
Database mounted.
SQL> alter database open resetlogs;
Database altered.
14) 打开后,指定表空间是OFFLINE的状态,符合闪回点的状态。
SQL> select * from knight.keyboards;
select * from knight.keyboards
*
ERROR at line1:
ORA-00376: file7 cannot be read at this time
ORA-01110: datafile 7: '/ss/offline_space01.dbf'
15)使表空间online
SQL> alter tablespace offline_space online;
Tablespace altered.
16) 没有新加入的数据
SQL> select * from knight.keyboards;
ID COMPANY TYPE
------------------------------ --------------------
1 IBM 500.55
2 HP 200.5
3 SONY 1200.5
4 ACER 55.6
5 MICROSOFT 108
闪回失败,闪回后无论数据还是数据文件状态都是操作点的状态,并且使用了隐含参数,需要做全库备份。
1)确定当前时间
SQL> select to_char(sysdate,'yyyy-mm-dd hh24:mi:ss') from dual;
TO_CHAR(SYSDATE,'YY
-------------------
2013-07-2720:56:32
2)确定当前SCN
SQL> select current_scn from v$database;
CURRENT_SCN
-----------
839748
3)查看表原始状态
SQL> select * from knight.books;
ID NAME PRICE
------------------------------ ----------
1 LINUX 25.55
2 AIX 50.5
3 NETWORK 125.89
4 JAVA 88.99
5 JQUERY 102.98
4) 插入新数据,这些数据在闪回后应该不存在。
SQL> insert into knight.books values(200,'WEBWORK',299.9);
1 row created.
5) 插入新数据,这些数据在闪回后应该不存在。
SQL> insert into knight.books values(201,'PMP',56.99);
1 row created.
SQL> commit;
Commit complete.
6) 表的新状态。
SQL> select * from knight.books;
ID NAME PRICE
------------------------------ ----------
200 WEBWORK 299.9
201 PMP 56.99
1 LINUX 25.55
2 AIX 50.5
3 NETWORK 125.89
4 JAVA 88.99
5 JQUERY 102.98
7 rows selected.
7) 将表空间离线
SQL> alter tablespace test_space offline;
Tablespace altered.
8)已经无法查询了
SQL> select * from knight.books;
select * from knight.books
*
ERROR at line1:
ORA-00376: file5 cannot be read at this time
ORA-01110: datafile 5: '/ss/test_space01.dbf'
9)模拟断电
SQL> shutdown abort;
ORACLE instance shut down.
10)启动至mount
SQL> startup mount;
ORACLE instance started.
Total System Global Area 1272213504 bytes
Fixed Size 1336260 bytes
Variable Size 822086716 bytes
Database Buffers 436207616 bytes
Redo Buffers 12582912 bytes
Database mounted.
11)闪回至指定SCN
SQL> flashback database to scn 839748;
Flashback complete.
12)查看数据文件状态,注意文件5是OFFLINE的状态。与闪回点状态不一致,与操作点状态一致。
SQL> select file#,status from v$datafile;
FILE# STATUS
-----------------
1 SYSTEM
2 RECOVER
3 RECOVER
4 RECOVER
5 OFFLINE
6 ONLINE
7 OFFLINE
8 RECOVER
8 rows selected.
13)打开数据库
SQL> alter database open resetlogs;
Database altered.
14)无法查看
SQL> select * from knight.books;
select * from knight.books
*
ERROR at line1:
ORA-00376: file5 cannot be read at this time
ORA-01110: datafile 5: '/ss/test_space01.dbf'
15)无法上线
SQL> alter tablespace test_space online;
alter tablespace test_space online
ERROR at line1:
ORA-01190: control file or data file 5 is from before the last RESETLOGS
ORA-01110: datafile 5: '/ss/test_space01.dbf'
无法上线
SQL> alter database datafile 5 online;
alter database datafile 5 online
*
ERROR at line1:
ORA-01190: control file or data file 5 is from before the last RESETLOGS
ORA-01110: datafile 5: '/ss/test_space01.dbf'
16)使用隐含参数
SQL> alter system set "_allow_resetlogs_corruption"=TRUE scope=spfile;
System altered.
SQL> ALTER SESSION SET EVENTS 'IMMEDIATE TRACE NAME ADJUST_SCN LEVEL1';
Session altered.
17)重启数据库至mount
SQL> shutdown immediate;
Database closed.
Database dismounted.
ORACLE instance shut down.
SQL> startup mount;
ORACLE instance started.
Total System Global Area 1272213504 bytes
Fixed Size 1336260 bytes
Variable Size 822086716 bytes
Database Buffers 436207616 bytes
Redo Buffers 12582912 bytes
Database mounted.
18)不完全恢复
SQL> recover database until cancel;
Media recovery complete.
19)此时可以上线
SQL> alter database datafile 5 online;
Database altered.
SQL> alter database open resetlogs;
Database altered.
20)报内部错误
SQL> select * from knight.books;
select * from knight.books
*
ERROR at line1:
ORA-00600:internal error code, arguments: [2662], [0], [840208], [0],
[840576],[20971648], [], [], [], [], [], []
21)再次重启
SQL> shutdown immediate;
ORA-00600:internal error code, arguments: [2662], [0], [840230], [0], [840576],[20971648], [], [], [], [], [], []
SQL> shutdown abort
ORACLE instance shut down.
SQL> startup nomount;
ORACLE instance started.
Total System Global Area 1272213504 bytes
Fixed Size 1336260 bytes
Variable Size 822086716 bytes
Database Buffers 436207616 bytes
Redo Buffers 12582912 bytes
SQL> alter database mount;
Database altered.
SQL> alter database open;
Database altered.
22)文件5已经上线
SQL> select file#,status from v$datafile;
FILE# STATUS
-----------------
1 SYSTEM
2 ONLINE
3 ONLINE
4 ONLINE
5 ONLINE
6 ONLINE
7 OFFLINE
8 ONLINE
8 rows selected.
23)可以查看,但结果不是闪回点的结果,而是操作点的结果。
SQL> select * from knight.books;
ID NAME PRICE
------------------------------ ----------
200 WEBWORK 299.9
201 PMP 56.99
1 LINUX 25.55
2 AIX 50.5
3 NETWORK 125.89
4 JAVA 88.99
5 JQUERY 102.98
7 rows selected.
全备数据库
从结果可以看出,新加入的记录被保存了,并没有按照被闪回到指定的时间点,由此说明,闪回数据库时是忽略操作点OFFLINE表空间的。但是此时SCN已经很乱了,必须全备数据库。
(完)