首页 > Linux操作系统 > Linux操作系统 > Flashback实验
Flashback实验
今天做这个实验,是有关于flashback的。首先看一下到底在什么情况下使用,oracle数据库中发生了逻辑损坏时可以使用闪回技术。什么是逻辑损坏?说白了就是你的数据文件还在,如果数据文件损坏就属于物理损坏。
那么逻辑损坏又有哪些?如果不小心删除了表,没关系,可以通过闪回从回收站找回来。如果你对表做了误操作,删除了数据,错误的更新了数据也可以闪回。
但这里强调一下如果你不小心删除了表空间,是没有办法通过flashback恢复的,只用通过rman或用户自定义备份通过原来(即表空间删除之前备份的控制文件)控制文件来恢复。下面开始试验,主要从三个级别来,闪回查询,闪回表,闪回数据库。
使用flashback有许多先觉条件,首先你得启用自动撤销表空间,然后每个等级的闪回也分别由不同的条件。
自动撤销表空间(Automatic Undo Managerment),这个在10g上都是默认启动的,可以看一下
SQL> show parameter undo
NAME TYPE VALUE
------------------------------------ ----------- ------------------------------
undo_management string AUTO
undo_retention integer 900
undo_tablespace string UNDOTBS1
我这里可以看到有三个参数undo_management auto 表明是自动管理,也可以改成手动manual,淡然如果你不清楚如何管理还是不要乱改的好。
undo_tablespace UNDOTBS1这个是系统默认的undo表空间,你也可以手工建一个create undo tablespace undo1 datafile ‘/opt/oracle/ora10g/undo1.dbf’ size 50m;如果udno表空间过小,肯定会影响到flashback,同时可能会触发ora-1555.
那么最后一个参数undo_retention这个是干什么的呢? 就是看是否retention guarantee,如果有,15分钟内一个transaction被committed后不会被覆盖。如果没有guarantee(既NOGUARANTEE),那么undo如果有空间就不会被覆盖,如果没有就会立即被覆盖。怎么查看是否guarantee?
SQL> select TABLESPACE_NAME,BLOCK_SIZE, RETENTION from dba_tablespaces where TABLESPACE_NAME='UNDOTBS1';
TABLESPACE_NAME BLOCK_SIZE RETENTION
------------------------------ ---------- -----------
UNDOTBS1 8192 NOGUARANTEE
1. 基于时间闪回
SQL> select * from students;
SNO SNAME SEX AGE BPLACE
------- -------- -------- ---- --------------------
95032 赵新3 男 20 新疆
95034 赵新4 男 20 新疆
95035 赵新5 男 20 新疆
95036 赵新6 男 20 新疆
95037 赵新7 男 20 新疆
95038 赵新8 男 20 新疆
95039 赵新9 男 20 新疆
95040 赵新10 男 20 新疆
95043 lily2 女 20 新疆
95044 lily3 女 20 新疆
95045 lily4 女 20 新疆
95046 lily5 女 20 新疆
95047 lily6 女 20 新疆
95048 lily8 女 20 新疆
95049 lily9 女 20 新疆
95050 lily10 女 20 新疆
95029 赵新 女 38 新疆
95031 赵新2 男 20 新疆
18 rows selected
这是students表,我们把其中的男同学删掉
SQL> delete from students where sex='男' ;
9 rows deleted
SQL> commit;
Commit complete
再查询一下
SQL> select * from students;
SNO SNAME SEX AGE BPLACE
------- -------- -------- ---- --------------------
95043 lily2 女 20 新疆
95044 lily3 女 20 新疆
95045 lily4 女 20 新疆
95046 lily5 女 20 新疆
95047 lily6 女 20 新疆
95048 lily8 女 20 新疆
95049 lily9 女 20 新疆
95050 lily10 女 20 新疆
95029 赵新 女 38 新疆
9 rows selected
SQL>
看到男同学都被删除了,大约过十分钟左右,我们使用闪回查询
SQL> select * from students as of timestamp sysdate-10/1440;
SNO SNAME SEX AGE BPLACE
------- -------- -------- ---- --------------------
95032 赵新3 男 20 新疆
95034 赵新4 男 20 新疆
95035 赵新5 男 20 新疆
95036 赵新6 男 20 新疆
95037 赵新7 男 20 新疆
95038 赵新8 男 20 新疆
95039 赵新9 男 20 新疆
95040 赵新10 男 20 新疆
95043 lily2 女 20 新疆
95044 lily3 女 20 新疆
95045 lily4 女 20 新疆
95046 lily5 女 20 新疆
95047 lily6 女 20 新疆
95048 lily8 女 20 新疆
95049 lily9 女 20 新疆
95050 lily10 女 20 新疆
95029 赵新 女 38 新疆
95031 赵新2 男 20 新疆
18 rows selected
SQL>
好,这是再删除男同学之前的表,我们再插入回students
SQL> insert into students select * from students as of timestamp sysdate-10/1440 where sex='男';
9 rows inserted
SQL> commit;
Commit complete
查询一下
SQL> select * from students;
SNO SNAME SEX AGE BPLACE
------- -------- -------- ---- --------------------
95043 lily2 女 20 新疆
95044 lily3 女 20 新疆
95045 lily4 女 20 新疆
95046 lily5 女 20 新疆
95047 lily6 女 20 新疆
95048 lily8 女 20 新疆
95049 lily9 女 20 新疆
95050 lily10 女 20 新疆
95029 赵新 女 38 新疆
95032 赵新3 男 20 新疆
95034 赵新4 男 20 新疆
95035 赵新5 男 20 新疆
95036 赵新6 男 20 新疆
95037 赵新7 男 20 新疆
95038 赵新8 男 20 新疆
95039 赵新9 男 20 新疆
95040 赵新10 男 20 新疆
95031 赵新2 男 20 新疆
18 rows selected
表已回复
2. 基于SCN闪回
查询SCN,查询SCN据我所知有两种方法
SQL> select dbms_flashback.get_system_change_number from dual;
GET_SYSTEM_CHANGE_NUMBER
------------------------
697126
SQL> select current_scn from v$database;
CURRENT_SCN
-----------
697128
SQL>
这两种有什么区别,我也不知道,反正都可以查
还是刚才那个表,我们把女同学都删除,
SQL> delete from students where sex='女';
9 rows deleted
SQL> commit;
Commit complete
SQL> select * from students;
SNO SNAME SEX AGE BPLACE
------- -------- -------- ---- --------------------
95032 赵新3 男 20 新疆
95034 赵新4 男 20 新疆
95035 赵新5 男 20 新疆
95036 赵新6 男 20 新疆
95037 赵新7 男 20 新疆
95038 赵新8 男 20 新疆
95039 赵新9 男 20 新疆
95040 赵新10 男 20 新疆
95031 赵新2 男 20 新疆
9 rows selected
SQL>
使用scn恢复
SQL> select * from students as of scn 697128;
SNO SNAME SEX AGE BPLACE
------- -------- -------- ---- --------------------
95043 lily2 女 20 新疆
95044 lily3 女 20 新疆
95045 lily4 女 20 新疆
95046 lily5 女 20 新疆
95047 lily6 女 20 新疆
95048 lily8 女 20 新疆
95049 lily9 女 20 新疆
95050 lily10 女 20 新疆
95029 赵新 女 38 新疆
95032 赵新3 男 20 新疆
95034 赵新4 男 20 新疆
95035 赵新5 男 20 新疆
95036 赵新6 男 20 新疆
95037 赵新7 男 20 新疆
95038 赵新8 男 20 新疆
95039 赵新9 男 20 新疆
95040 赵新10 男 20 新疆
95031 赵新2 男 20 新疆
18 rows selected
SQL>
SQL> insert into students select * from students as of scn 697128 where sex='女';
9 rows inserted
SQL> commit;
Commit complete
已经恢复
其实scn就是oracle中的时间,只不过使用oracle使用scn作为数据库的时间基准
通过查询
SQL> select scn ,to_char(time_dp, 'yyyy-mm-dd hh24:mm:ss') from sys.smon_scn_time;
SCN TO_CHAR(TIME_DP,'YYYY-MM-DDHH2
---------- ------------------------------
689961 2010-12-01 17:12:56
690457 2010-12-01 17:12:53
690712 2010-12-01 17:12:57
690924 2010-12-01 17:12:51
693199 2010-12-01 17:12:01
693413 2010-12-01 17:12:01
693666 2010-12-01 17:12:52
693724 2010-12-01 17:12:52
694409 2010-12-01 17:12:46
694658 2010-12-01 17:12:56
694941 2010-12-01 17:12:59
695095 2010-12-01 17:12:53
695610 2010-12-01 17:12:57
695904 2010-12-01 18:12:51
695986 2010-12-01 18:12:07
696242 2010-12-01 18:12:12
696945 2010-12-01 18:12:13
697157 2010-12-01 18:12:17
697351 2010-12-01 18:12:11
697825 2010-12-01 18:12:17
3. 版本查询
VERSIONS BETWEEN 是这样一种查询,当你表进行过多次修改,连你自己也不清楚改了几次,你需要把你做了什么操作都显示出来,以来恢复。
当前scn
SQL> select dbms_flashback.get_system_change_number from dual;
GET_SYSTEM_CHANGE_NUMBER
------------------------
718751
先删两个男同学,
delete from students where sno=95032 or sno=95044;scn= 718796
再删两个女同学
delete from students where sno=95043 or sno=95045;scn= 718874
删掉所有男同学
delete from students where sex='男';scn= 718948
删掉所有女同学
delete from students where sex='女';scn= 718967
查看版本结果
SQL> select SNO,SNAME,SEX,AGE,BPLACE,versions_startscn,versions_endscn,versions_operation
2 from students versions between scn 718751 and 718967 order by 1;
SNO SNAME SEX AGE BPLACE VERSIONS_STARTSCN VERSIONS_ENDSCN VERSIONS_OPERATION
------- -------- -------- ---- -------------------- ----------------- --------------- ------------------
95029 赵新 男 20 新疆 718928
95029 赵新 男 20 新疆 718928 D
95030 赵新1 男 20 新疆 718928 D
95030 赵新1 男 20 新疆 718928
95031 赵新2 男 20 新疆 718928 D
95031 赵新2 男 20 新疆 718928
95032 赵新3 男 20 新疆 718790
95032 赵新3 男 20 新疆 718790 D
95034 赵新4 男 20 新疆 718928
95034 赵新4 男 20 新疆 718928 D
95035 赵新5 男 20 新疆 718928 D
95035 赵新5 男 20 新疆 718928
95036 赵新6 男 20 新疆 718928
95036 赵新6 男 20 新疆 718928 D
95037 赵新7 男 20 新疆 718928 D
95037 赵新7 男 20 新疆 718928
95038 赵新8 男 20 新疆 718928
95038 赵新8 男 20 新疆 718928 D
95039 赵新9 男 20 新疆 718928 D
95039 赵新9 男 20 新疆 718928
SNO SNAME SEX AGE BPLACE VERSIONS_STARTSCN VERSIONS_ENDSCN VERSIONS_OPERATION
------- -------- -------- ---- -------------------- ----------------- --------------- ------------------
95040 赵新10 男 20 新疆 718928 D
95040 赵新10 男 20 新疆 718928
95041 lily 女 20 新疆 718964
95041 lily 女 20 新疆 718964 D
95042 lily1 女 20 新疆 718964 D
95042 lily1 女 20 新疆 718964
95043 lily2 女 20 新疆 718852
95043 lily2 女 20 新疆 718852 D
95044 lily3 女 20 新疆 718790
95044 lily3 女 20 新疆 718790 D
95045 lily4 女 20 新疆 718852 D
95045 lily4 女 20 新疆 718852
95046 lily5 女 20 新疆 718964
95046 lily5 女 20 新疆 718964 D
95047 lily6 女 20 新疆 718964 D
95047 lily6 女 20 新疆 718964
95048 lily8 女 20 新疆 718964 D
95048 lily8 女 20 新疆 718964
95049 lily9 女 20 新疆 718964 D
95049 lily9 女 20 新疆 718964
95050 lily10 女 20 新疆 718964 D
SNO SNAME SEX AGE BPLACE VERSIONS_STARTSCN VERSIONS_ENDSCN VERSIONS_OPERATION
------- -------- -------- ---- -------------------- ----------------- --------------- ------------------
95050 lily10 女 20 新疆 718964
42 rows selected
Flashback的事务查询时通过查询flashback_transaction_query视图来实现的。通过查询该视图能够获得一些事务执行时的信息,甚至包括undo语句。
查看当前scn:
SQL> select dbms_flashback.get_system_change_number from dual;
GET_SYSTEM_CHANGE_NUMBER
------------------------
723625
首先删除一条记录:
SQL> delete from students where sno=95030;
1 row deleted
使用Transaction query
select xid,commit_scn,commit_timestamp,operation,undo_sql
from flashback_transaction_query q where q.xid in(
select versions_xid from lsy.students versions between scn 723625 and 725223);
但是报了一个错:
ORA-30052: invalid lower limit snapshot expression
百度了一下,发现是有关于undo_retention=900s的原因,我在15分钟内并没有做过大规模dml操作,也就是应该把undo数据覆盖掉。可能是我两次scn的时间超过了15分钟。
这里我有一个疑问,用select * from students as of scn 723625;可以查询到该scn表的数据,但是使用version between scn 723625 and 725223 就会报:
ORA-30052: invalid lower limit snapshot expression
如果说被覆盖的话查询scn723625是查询不到的。
我们继续在做一遍删除操作,并记录下scn,重新:
SQL> select xid,commit_scn,commit_timestamp,operation,undo_sql
2 from flashback_transaction_query q where q.xid in(
3 select versions_xid from lsy.students versions between scn 726320 and 726358);
XID COMMIT_SCN COMMIT_TIMESTAMP OPERATION UNDO_SQL
---------------- ---------- ---------------- -------------------------------- --------------------------------------------------------------------------------
09000700F2010000 726340 2010-12-2 0:35:2 DELETE insert into "LSY"."STUDENTS"("SNO","SNAME","SEX","AGE","BPLACE") values ('95031'
09000700F2010000 726340 2010-12-2 0:35:2 BEGIN
大家可以看到undo数据了 。
这还是flashback_transaction_query表的数据,最早的scn可以追寻到718291,但是却报错,那么肯定是这句select versions_xid from lsy.students versions between scn 723625 and 725223。究竟为什么还得找个大神解释一下。
前面说了一下闪回查询,下面说一下闪回表。这个粒度要大于闪回查询。闪回查询都是查询到表先前的数据,再把误操作的数据改回去。
闪回表可以从两个地方恢复,一个是回收站(recycle bin),另一个就是从undo数据中。
首先drop掉student这个表
SQL> drop table students;
Table dropped
然后恢复
SQL> flashback table students to before drop;
Done
SQL> select * from students;
SNO SNAME SEX AGE BPLACE
------- -------- -------- ---- --------------------
95032 赵新3 男 20 新疆
95029 赵新 男 20 新疆
95034 赵新4 男 20 新疆
95035 赵新5 男 20 新疆
95036 赵新6 男 20 新疆
95037 赵新7 男 20 新疆
95038 赵新8 男 20 新疆
95039 赵新9 男 20 新疆
95040 赵新10 男 20 新疆
95041 lily 女 20 新疆
95042 lily1 女 20 新疆
95043 lily2 女 20 新疆
95044 lily3 女 20 新疆
95045 lily4 女 20 新疆
95046 lily5 女 20 新疆
95047 lily6 女 20 新疆
95048 lily8 女 20 新疆
95049 lily9 女 20 新疆
95050 lily10 女 20 新疆
19 rows selected
很简单,这里多说两句,如果你想彻底删除表,连recycle bin 里都不放可以使用purge命令:
清除指定表:purge table ;
??清除当前用户的回收站:purge recyclebin;
??清除所有用户的回收站:purge dba_recyclebin;
如果你已经建立要恢复的表,这时候是需要在后面加上rename to即可
flashback table students to before drop rename to stu1;
当然也可以查询recycle bin里面的内容
表恢复以后,recycle bin里的相关内容也随之消失,和windows回收站很相似。
查询当前scn
SQL> select dbms_flashback.get_system_change_number from dual;
GET_SYSTEM_CHANGE_NUMBER
------------------------
748700
这个也很简单 ,我们先删除表students中的内容
SQL> delete students;
19 rows deleted
SQL> commit;
Commit complete
SQL>
恢复表students
SQL> flashback table students to scn 748700;
flashback table students to scn 748700
ORA-08189: cannot flashback the table because row movement is not enabled
SQL>
哎呦报错了,row movement没有打开,这里补充一下要使用UNDO恢复表,必须要打开row movement。
我们先来打开row movement
SQL> alter table students enable row movement;
Table altered
下面再来恢复
SQL> flashback table students to scn 748700;
Done
好了恢复了,使用timestamp和scn是一个道理我就不重复了
如果你的数据文件没有损坏,同时你对你数据库的表了如指掌,那么使用闪回数据库还是很方便的。
当然使用数据库闪回也是有条件的
首先数据库必须启用了flashback database
数据库必须打开了flash recovery area
数据库必须在归档模式下
1. 检查数据库是否处于归档模式
SQL> archive log list;
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>
2. 检出数据库是否启用了flashback database
SQL> select flashback_on , force_logging from v$database;
FLASHBACK_ON FORCE_LOGGING
------------------ -------------
NO NO
关闭的把他打开
SQL> alter database force logging;
Database altered
这个参数可以下数据库open的情况下打开
SQL> alter database flashback on;
alter database flashback on
ORA-38759: Database must be mounted by only one instance and not open.
SQL
这个就不可以了,必须在mount状态下打开
SQL> startup mount;
ORACLE instance started.
Total System Global Area 159383552 bytes
Fixed Size 1218292 bytes
Variable Size 134220044 bytes
Database Buffers 20971520 bytes
Redo Buffers 2973696 bytes
Database mounted.
SQL> alter database flashback on;
Database altered.
SQL>
好了
再检查一下
SQL> select flashback_on , force_logging from v$database;
FLASHBACK_ON FORCE_LOGGING
------------------ -------------
YES YES
3. 检查数据库是否打开了flash recovery area
SQL> show parameter db_recovery_file;
NAME TYPE VALUE
------------------------------------ ----------- ------------------------------
db_recovery_file_dest string /opt/ora10g/flash_recovery_area
db_recovery_file_dest_size big integer 1G
下面我们开始做闪回数据库的实验:
取得scn
SQL> select dbms_flashback.get_system_change_number from dual;
GET_SYSTEM_CHANGE_NUMBER
------------------------
751811
删除表students
SQL> drop table students;
Table dropped
必须把数据库改到mounted状态,才能闪回数据库
SQL> select status from v$instance;
STATUS
------------
MOUNTED
SQL>
闪回数据库
SQL> flashback database to scn 751811;
Flashback complete.
接着以resetlogs模式打开
SQL> alter database open resetlogs;
Database altered.
验证数据
SQL> select * from students;
SNO SNAME SEX AGE BPLACE
------- -------- -------- ---- --------------------
95032 赵新3 男 20 新疆
95029 赵新 男 20 新疆
95034 赵新4 男 20 新疆
95035 赵新5 男 20 新疆
95036 赵新6 男 20 新疆
95037 赵新7 男 20 新疆
95038 赵新8 男 20 新疆
95039 赵新9 男 20 新疆
95040 赵新10 男 20 新疆
95041 lily 女 20 新疆
95042 lily1 女 20 新疆
95043 lily2 女 20 新疆
95044 lily3 女 20 新疆
95045 lily4 女 20 新疆
95046 lily5 女 20 新疆
95047 lily6 女 20 新疆
95048 lily8 女 20 新疆
95049 lily9 女 20 新疆
95050 lily10 女 20 新疆
19 rows selected
SQL
数据恢复
最后再解释一下一个参数
SQL> show parameter flash
NAME TYPE VALUE
------------------------------------ ----------- ------------------------------
db_flashback_retention_target integer 1440
这个参数是干什么的呢?是不是和undo_retention有点像
该参数用来控制 flashback log 数据保留的时间,或者说,你希望 flashback database 能够恢复的最早的时间点。默认值是 1440 ,单位是 minute ,即 24 小时,需要注意的是该参数虽然未直接指定 flash recovery area大小,但却受其制约,举个例子假如数据库每天有 10% 左右的数据变动的话,如果该初始化参数值设置为1440 ,则 flash recovery area 的大小至少要是当前数据库实际容量的 10% ,如果该初始化参数设置为 2880 ,则 flash recovery area 的 大小就至少是数据库所占容量的 20%。
2010-12-15 by饼干
来自 “ ITPUB博客 ” ,链接:https://blog.itpub.net/23493401/viewspace-681951/ ,如需转载,请注明出处,否则将追究法律责任。