本文章为网络笔记,看了warehouse老师的视频受益匪浅,更是感觉自己技术太过初级,特写了本笔记,方便以后反复学习!
如有任何不妥,请发邮件至102448567@qq.com删除文章!
关于warehouse:
http://blog.itpub.net/19602/viewspace-1059211/
flashback
是从9i
引进的概念,flashbackOracle
一共支持六种,大多数依赖于undo,每一种都有其使用场景,机制也不一样
1.flashbackup query(闪回查询)原理就是利用undo
语法示例:
时间只是到秒,时间戳更精细,到了微秒
scn
可以与时间戳进行转化
scn
到时间戳
时间戳转化成scn
2.flashback table(undo
)也是利用的undo
闪回表只能闪回DML
操作(insert,update,delete
),不能闪回DDL
操作,因为DDL
操作修改的是数据字典
sys
用户是不支持闪回的
但是在建表的时候默认他的rowid
是不能发生变化的,这样就和闪回矛盾了,因为闪回回来之后rowid
可能变化也可能不变化
闪回表的首要条件就是row_movement
要是enable
的
下面实验测试rowid
发生变化的情况
两条数据的rowid
都变化了
3.flashback versions query
作用:我们在一张表上做了哪些动作,Oracle
可以帮助我们做一个慢动作回放,一点点查看对这张表上做了哪些动作,也是依赖undo
示例:
SQL> show user
USER is "SCOTT"
SQL> create table tt (id int,name varchar2(20));
Table created.
SQL> insert into tt values(1,'a');
1 row created.
SQL> insert into tt values(2,'b');
1 row created.
SQL> commit;
Commit complete.
SQL> insert into tt values(3,'c');
1 row created.
SQL> insert into tt values(4,'d');
1 row created.
SQL> commit;
Commit complete.
SQL> insert into tt values(5,'e');
1 row created.
SQL> insert into tt values(6,'f');
1 row created.
SQL> commit;
Commit complete.
SQL>
SQL> select * from tt;
ID NAME
---------- ------------------------------------------------------------
1 a
2 b
3 c
4 d
5 e
6 f
6 rows selected.
SQL> update tt set name='aaa' where id=1;
1 row updated.
SQL> commit;
Commit complete.
SQL> update tt set name='bbb' where id=2;
1 row updated.
SQL> update tt set name='ccc' where id=3;
1 row updated.
SQL> commit;
Commit complete.
SQL> delete from tt where id=6;
1 row deleted.
SQL> commit;
SQL> select *from tt;
ID NAME
---------- ------------------------------------------------------------
1 aaa
2 bbb
3 ccc
4 d
5 e
5 rows selected.
select versions_startscn,versions_endscn,versions_xid,versions_operation,versions_starttime,versions_endtime,id,name
from tt versions between scn minvalue and maxvalue order by 1
SQL> update tt set name='eee' where id=5;
1 row updated.
SQL> rollback;
Rollback complete.
SELECT versions_startscn,
versions_endscn,
versions_xid,
versions_operation,
versions_starttime,
versions_endtime, ##上面这些都是伪列
id,
name
FROM tt versions BETWEEN scn minvalue AND maxvalue
ORDER BY 1
下面一行数据都没有了是因为下图是第二天接着做实验昨天的数据没有了,但是也能说明没有commit
是不会记录到version query
的
没有commit
是不会出现在flashback versions query
里的
SQL> update tt set name='eee' where id=5;
1 row updated.
SQL> commit;
Commit complete.
如果VERSIONS_STARTSCN
为空,表示在查询范围外创建的,flashback versions query
不能做到实现闪回,他和falshback transaction query
配合
4.flashback transaction query
这个里面数据量非常大,内容来源于undo
select * from flashback_transaction_query
flashback versions query
最重要的就是确定事务id
利用上图第一行的事务id
:03000D00A2030000
,觉得update
错了,就通过flashback versions query
确定事务id
,之后就可以通过flashback_transaction_query
视图查询相关的信息
select * from flashback_transaction_query where xid='03000D00A2030000';
上图undo_sql
为空这个问题是Oracle 11g
默认把 supplemental logging
禁用了导致的。
sys
用户执行打开就可以了
alter database add supplemental log data;
正常如下图
之前是执行的语句是update tt set name = 'eee' where id = 5;undo_sql
中刚好是反转过来了
5.flashback drop
以上五种都是跟undo
有关,以下两种就跟undo
没有关系了,放在system
表空间中的表是不能flashback drop
的,DDL
命令操作的都是数据字典,修改的都是元数据,10g
之前,drop
就是把元数据删掉了,数据还在,10g
开始drop
只是把表重命名了
SQL> show user;
USER is "SCOTT"
SQL> create table t1 (id int) tablespace system;
Table created.
SQL> drop table t1;
Table dropped.
SQL> show recyclebin;
这张表是在system
表空间里,drop
之后没有在recyclebin
里,system
表空间里的对象不支持闪回
SQL> create table t1(id int) tablespace users;
Table created.
SQL> drop table t1;
Table dropped.
SQL> show recyclebin;
ORIGINAL NAME RECYCLEBIN NAME OBJECT TYPE DROP TIME
---------------- ------------------------------ ------------ -------------------
T1 BIN$rH77jNORE5DgU+AjEAoFpQ==$0 TABLE 2020-08-10:11:59:34
表在users
表空间中drop
之后就会出现在recyclebin
,recyclebin
中最后删除的出现在第一行,recyclebin
中的信息来源于Oracle
中的一个视图
select * from dba_recyclebin;
这个对象还是能够查询的,这里没有数据是因为之前创建的时候就没有插入数据,但是回收站里的对象不能做DML
操作
SQL> insert into "BIN$rH77jNORE5DgU+AjEAoFpQ==$0" values(1);
insert into "BIN$rH77jNORE5DgU+AjEAoFpQ==$0" values(1)
*
ERROR at line 1:
ORA-38301: 无法对回收站中的对象执行 DDL/DML
这样表就回来了
SQL> flashback table t1 to before drop;
Flashback complete.
SQL> select * from t1;
no rows selected
跟表直接依赖的还有触发器和索引,这些是直接依赖的对象,还有引用表的对象,比如存储过程、包、函数,表删除以后这些直接依赖的对象也被删除了,间接引用的对象不会被删除只是被标记成无效的
创建索引,删除表之后,索引不在recyclebin
里
SQL> show user
USER is "SCOTT"
SQL> create index inx_t1 on t1(id) tablespace system;
Index created.
SQL> drop table t1;
Table dropped.
SQL> show recyclebin;
ORIGINAL NAME RECYCLEBIN NAME OBJECT TYPE DROP TIME
---------------- ------------------------------ ------------ -------------------
T1 BIN$rIG94sUXGbTgU+AjEArFpA==$0 TABLE 2020-08-10:15:17:05
SQL> flashback table t1 to before drop;
Flashback complete
表恢复回来之后索引还在,但是名字变了,原来是inx_t1
名字变成了回收站中名字的格式,触发器也是这样的,因为有名字被占用的风险,索引名字不影响使用,所以Oracle
没有把他恢复成原来的名字,但是为了发生误会,还是要改一下名字
SQL> alter index "BIN$rIG94sUWGbTgU+AjEArFpA==$0" rename to inx_t1;
Index altered.
SQL> conn / as sysdba
Connected.
SQL> select index_name from dba_indexes where table_name='T1';
INDEX_NAME
-----------------------
INX_T1
对象中只有表是支持闪回的
SQL> drop index inx_t1;
Index dropped.
SQL> show recyclebin;
这个索引之前是创建在system
表空间的,再创建一个users
表空间的删除之后也没有出现在recyclebin
里
SQL> drop index inx_t1;
Index dropped.
SQL> create index inx_t1 on t1(id) tablespace users;
Index created.
SQL> drop index inx_t1;
Index dropped.
SQL> show recyclebin;
删除一张表,元数据被重命名了,数据原封没动,磁盘没有被释放
手动释放(这个只删除自己的recyclebin
)
SQL> purge recyclebin;
Recyclebin purged.
自动释放
如果表空间里有可用空间,使用率没有到达百分之百,这时候Oracle
优先使用这些空间,不会删除recyclebin
,第二种情况,表空间和数据文件没有空间了数据文件需要自动扩展的时候,这时候Oracle
优先清理recyclebin
删除表不进回收站
SQL> drop table t1 purge;
Table dropped.
闪回drop
是把误删除的表恢复回来,修改的元数据,闪回table
修复误删除的数据,执行的是DML
操作,闪回drop
没有利用undo
,利用的是recyclebin
查看是否启用recyclebin
SQL> show parameter recyclebin;
NAME TYPE VALUE
------------------------------------ --------------------------------- ------------------------------
recyclebin string on
6.flashback database(依赖闪回日志,原理是不完全恢复)
查看是否开启了flashback database(默认不启用)
SQL> select flashback_on from v$database;
FLASHBACK_ON
------------------------------------------------------
NO
启用要满足的条件
1.archivelog
2.必须使用flash recovery area
(查看db_recovery_file_dest
是否为空)
激活了flashback database
就要产生闪回日志,db_recovery_file_dest
就是放闪回日志的
SQL> show parameter db_recovery_file_dest;
NAME TYPE VALUE
------------------------------------ --------------------------------- ------------------------------
db_recovery_file_dest string +ARCH
db_recovery_file_dest_size big integer 4977M
SQL> shu immediate;
Database closed.
Database dismounted.
ORACLE instance shut down.
SQL> startup mount;
ORACLE instance started.
Total System Global Area 622149632 bytes
Fixed Size 2255792 bytes
Variable Size 234882128 bytes
Database Buffers 377487360 bytes
Redo Buffers 7524352 bytes
Database mounted.
SQL>
归档模式
SQL> archive log list;
Database log mode Archive Mode
Automatic archival Enabled
Archive destination USE_DB_RECOVERY_FILE_DEST
Oldest online log sequence 62
Next log sequence to archive 64
Current log sequence 64
SQL> alter database flashback on;
Database altered.
SQL> select flashback_on from v$database;
FLASHBACK_ON
------------------------------------------------------
YES
SQL> alter database open;
Database altered.
flashback database
能让数据库后退到某一个scn
ASMCMD> pwd
+arch/orcl
ASMCMD> ls
ARCHIVELOG/
CONTROLFILE/
FLASHBACK/ ##这里就存放闪回日志
ONLINELOG/
闪回日志是Oracle自动管理的
ASMCMD> pwd
+arch/orcl/flashback
ASMCMD> ls
log_1.271.1048090019
log_2.272.1048090021
闪回日志的大小是数据块的整数倍
SQL> select * from v$bgprocess where paddr<>'00';
PADDR PSERIAL# NAME DESCRIPTION ERROR
---------------- ---------- --------------- ---------------------------------------- ----------
00000000848A9C20 1 PMON process cleanup ##########
00000000848ABD90 1 VKTM Virtual Keeper of TiMe process ##########
00000000848ACE48 1 GEN0 generic0 ##########
00000000848ADF00 1 DIAG diagnosibility process ##########
00000000848AEFB8 1 DBRM DataBase Resource Manager ##########
00000000848AACD8 1 PSP0 process spawner 0 ##########
00000000848B0070 1 DIA0 diagnosibility process 0 ##########
00000000848B1128 1 MMAN Memory Manager ##########
00000000848B21E0 1 DBW0 db writer process 0 ##########
00000000848C1CA8 2 ARC0 Archival Process 0 ##########
00000000848C2D60 1 ARC1 Archival Process 1 ##########
PADDR PSERIAL# NAME DESCRIPTION ERROR
---------------- ---------- --------------- ---------------------------------------- ----------
00000000848C3E18 1 ARC2 Archival Process 2 ##########
00000000848C4ED0 1 ARC3 Archival Process 3 ##########
00000000848B3298 1 LGWR Redo etc. ##########
00000000848B4350 1 CKPT checkpoint ##########
00000000848BEA80 2 RVWR Recovery Writer ########## 就是这个进程写闪回日志
00000000848B5408 1 SMON System Monitor Process ##########
00000000848CA268 5 SMCO Space Manager Process ##########
00000000848B64C0 1 RECO distributed recovery ##########
00000000848C91B0 2 CJQ0 Job Queue Coordinator ##########
00000000848C5F88 1 QMNC AQ Coordinator ##########
00000000848B7578 1 RBAL ASM Rebalance master ##########
PADDR PSERIAL# NAME DESCRIPTION ERROR
---------------- ---------- --------------- ---------------------------------------- ----------
00000000848B8630 1 ASMB ASM Background ##########
00000000848BC910 1 MARK mark AU for resync koordinator ##########
00000000848B96E8 1 MMON Manageability Monitor Process ##########
00000000848BA7A0 1 MMNL Manageability Monitor Process 2 ##########
26 rows selected.
SQL> select * from v$flashback_database_log;
OLDEST_FLASHBACK_SCN OLDEST_FLASHBACK_TI RETENTION_TARGET FLASHBACK_SIZE ESTIMATED_FLASHBACK_SIZE
-------------------- ------------------- ---------------- -------------- ------------------------
1078353 2020-08-10 16:06:58 1440 104857600 0
oldest_flashback_scn是数据库能闪回的最小scn
SQL> select * from v$flashback_database_logfile;
NAME LOG# THREAD# SEQUENCE# BYTES FIRST_CHANGE# FIRST_TIME TYPE
-------------------------------------------------- ---------- ---------- ---------- ---------- ------------- ------------------- ---------------------------
+ARCH/orcl/flashback/log_1.271.1048090019 1 1 1 52428800 1078593 2020-08-10 16:06:58 NORMAL
+ARCH/orcl/flashback/log_2.272.1048090021 2 1 1 52428800 0 RESERVED
这个视图就跟闪回日志有关,有几个日志就有几条记录
原理:当前数据库的scn
是1079896
,v$flashback_database_log
中oldest_flashback_scn
是1078353
,要闪回这两个scn
之间任一个scn
,比如1078965
,这时候就需要1078965
这个点之前的完整备份还有备份之后的归档日志这相当于不完全恢复,但是闪回数据库不做不完全恢复,就要通过flashback database
数据库的功能把scn退回到1078965
,不完全恢复是要restore database
就是重建数据文件,现在是要通过现有的文件(数据文件,控制文件,redo
)退回到1078965
,这个时候的数据库文件里的scn
肯定是要比1078965
大,现有的数据库文件加上闪回日志就能把scn
推到1078965
之前,然后加上归档日志,到1078965
,闪回日志里记录的是撤销数据块的操作,不一定是过去的数据块的完全备份,操作一下块就备份一下,这样日志量太大了
SQL> select current_scn from v$database;
CURRENT_SCN
-----------
1080265
SQL> drop user scott cascade;
User dropped.
SQL> shu immediate;
Database closed.
Database dismounted.
ORACLE instance shut down.
SQL> startup mount
ORACLE instance started.
Total System Global Area 622149632 bytes
Fixed Size 2255792 bytes
Variable Size 234
882128 bytes
Database Buffers 377487360 bytes
Redo Buffers 7524352 bytes
Database mounted.
SQL> flashback database to scn 1080265;
Flashback complete.
SQL> alter database open resetlogs;
Database altered.
SQL> select username from dba_users;
USERNAME
SCOTT
总结:flashback query
利用undo
,这个只能看,flashback table
也是利用undo
,修改数据发生错误的时候想要撤销掉这是针对某一个表,如果一个事务修改了很多表,那就不能一张一张的flachback table
这样容易发生错误,这时候就要用flashback transaction query
,首先要确定transaction id
,transaction id
就要通过flashback versions query
确定,flashback versions query
就是慢动作回放,flashback drop
就是针对drop table
,flashback database
动作有点大, 生产很少开启flashback database
,Oracle
中安全和性能就是天平的两端。DML
越多,闪回日志就会很大,闪回日志不能手动维护是Oracle
自动维护,有参数控制闪回日志在闪回恢复区里保留默认24
小时,但是发现超过这个时间Oracle
也不会自动删除闪回日志,只有当把flashback database
关闭的时候Oracle
会自动删除闪回日志
SQL> show parameter db_flashback
NAME TYPE VALUE
------------------------------------ --------------------------------- ------------------------------
db_flashback_retention_target integer 1440 单位是分钟,默认是24小时
闪回恢复区的使用情况
SQL> select * from v$flash_recovery_area_usage;
FILE_TYPE PERCENT_SPACE_USED PERCENT_SPACE_RECLAIMABLE NUMBER_OF_FILES
-------------------- ------------------ ------------------------- ---------------
CONTROL FILE .2 0 1
REDO LOG 3.07 0 3
ARCHIVED LOG 10.39 0 14
BACKUP PIECE 0 0 0
IMAGE COPY 0 0 0
FLASHBACK LOG 2.05 0 2
FOREIGN ARCHIVED LOG 0 0 0
7 rows selected.
Oracle 11g
可以创建一个表空间专门放闪回的东西,这样就可控了