Article Directory
1 Overview
- In order to quickly restore an Oracle database from erroneous operation, Oracle introduced Flashback technology .
- This blog, the main share Flashback technology Flashback Query, Flashback Transaction Query, Flashback Versions Query, Flashback Table and Flashback Drop for Flashback Database and Flashback archive , the scope is too broad, is not recommended .
Query the current system timestamp and SCN
SELECT to_char(SYSDATE, 'YYYY-MM-HH hh24:mi:ss:mm') timestamp,
timestamp_to_scn(SYSDATE) scn
FROM dual;
2 Example description
2.1 Flashback query
- Role: query data before a certain period of time in the past
- Note: commit time
grammar:
select *
from table_name
[as of timestamp | scn expression]
[where condition]
Basic data: insert 3 records and perform flashback query
CREATE TABLE flashback_select_test (
ID NUMBER,
NAME VARCHAR2(30),
create_date DATE,
create_scn NUMBER
);
-- 设置时间格式,查看方便
ALTER SESSION SET nls_date_format = 'YYYY/MM/DD HH24:MI:SS';
-- insert 语句,执行间隔 几秒钟,方便测试
INSERT INTO flashback_select_test
(id, NAME, create_date, create_scn)
VALUES
(1, 'a', SYSDATE, timestamp_to_scn(SYSDATE));
COMMIT;
INSERT INTO flashback_select_test
(id, NAME, create_date, create_scn)
VALUES
(2, 'b', SYSDATE, timestamp_to_scn(SYSDATE));
COMMIT;
INSERT INTO flashback_select_test
(id, NAME, create_date, create_scn)
VALUES
(3, 'c', SYSDATE, timestamp_to_scn(SYSDATE));
COMMIT;
data verification:
SELECT * FROM flashback_select_test;
SELECT * FROM flashback_select_test AS OF TIMESTAMP to_timestamp('2020/8/3 22:21:04', 'YYYY/MM/DD HH24:MI:SS');
SELECT * FROM flashback_select_test AS OF SCN 12614250;
Query screenshot:
2.2 Flashback version query
- When the record changes, commit time happens to be recorded, available Flashback Query (under normal circumstances, we would not deliberately go record this time)
- If there is no record, then use the Flashback Versions Query
- Role: You can query all the submitted records
grammar:
select *
from table_name
versions between scn expr | timestamp minvalue
and expr | maxvalue [as of scn | timestamp expr];
1. between ... and: 时间段
2. scn | timestamp:时间格式(系统变更号 | 时间戳)
3. minvalue | maxvalue:时间取值(最小值 | 最大值)
4. 可使用的伪列
(1) versions_starttime : 基于 时间 的版本有效范围下界
(2) versions_startscn : 基于 SCN 的版本有效范围下界
(3) versions_endtime : 基于 时间 的版本有效范围上界
(4) versions_endscn : 基于 SCN 的版本有效范围上界
(5) versions_xid : 操作的事务 ID
(6) versions_operation : 执行操作的类型. I: insert、U: delete、D: DELETE
Demonstration: (When the DML statement is executed, the interval is a few seconds, which is convenient for observation)
CREATE TABLE flashback_versions_test (
ID NUMBER,
NAME VARCHAR2(30)
);
-- 下列语句执行时,间隔几秒钟,方便观察
INSERT INTO flashback_versions_test(ID, NAME) VALUES(1, '瑶瑶');
COMMIT;
INSERT INTO flashback_versions_test(ID, NAME) VALUES(2, '倩倩');
COMMIT;
UPDATE flashback_versions_test t SET t.name = '倩倩123' WHERE t.id = 2;
COMMIT;
INSERT INTO flashback_versions_test(ID, NAME) VALUES(3, '优优');
COMMIT;
Flashback version query statement:
SELECT id,
NAME,
to_char(versions_starttime, 'YYYY-MM-DD HH24:MI:SS') versions_starttime,
to_char(versions_endtime, 'YYYY-MM-DD HH24:MI:SS') versions_endtime,
versions_startscn,
versions_endscn,
versions_xid,
versions_operation
FROM flashback_versions_test versions BETWEEN TIMESTAMP minvalue AND maxvalue
ORDER BY versions_starttime;
search result:
2.3 Flashback transaction query
- Flashback Transaction Query is actually Flashback Versions Query an expanded audit of a transaction through which you can even undo a transaction has been submitted.
Prerequisite knowledge understanding:
SELECT t.*
FROM flashback_transaction_query t
WHERE t.logon_user = 'SYSTEM'; -- 你登录的用户
-- GRANT SELECT ANY TRANSACTION TO scott; -- 测试用户,若权限不足,需授权
-- 添加补充日志 (若没有 undo_sql 为空)
SELECT t.supplemental_log_data_min, t.* FROM v$database t; -- YSE: 开启
ALTER DATABASE ADD SUPPLEMENTAL LOG DATA; -- 开启语句
Basic data preparation: suppose that when updating, forget to bring the where condition
CREATE TABLE flashback_transaction_query_ts (
ID NUMBER,
NAME VARCHAR2(30),
create_date DATE
);
-- insert 语句,间隔 几秒钟,方便观察
INSERT INTO flashback_transaction_query_ts
(id, NAME, create_date)
VALUES
(1, '小游子', SYSDATE);
COMMIT;
INSERT INTO flashback_transaction_query_ts
(id, NAME, create_date)
VALUES
(2, '小优子', SYSDATE);
COMMIT;
INSERT INTO flashback_transaction_query_ts
(id, NAME, create_date)
VALUES
(3, '小倩子', SYSDATE);
COMMIT;
-- 假设本来想更新 id = 2 的记录,结果忘记写条件 where id = 2
UPDATE flashback_transaction_query_ts t SET t.name = '小优子22';
COMMIT;
data verification:
1. 首先使用 闪回版本查询,查询 事务id
SELECT id,
NAME,
to_char(versions_starttime, 'YYYY-MM-DD HH24:MI:SS') versions_starttime,
to_char(versions_endtime, 'YYYY-MM-DD HH24:MI:SS') versions_endtime,
versions_startscn,
versions_endscn,
versions_xid,
versions_operation
FROM flashback_transaction_query_ts versions BETWEEN TIMESTAMP minvalue AND maxvalue
ORDER BY versions_starttime;
2. 根据 事务id,获取 undo_sql
SELECT t.*
FROM flashback_transaction_query t
WHERE t.logon_user = 'SYSTEM'
AND t.xid = '08001C00AB1F0000';
Test Results:
-- undo_sql 复制如下:
1 update "SYSTEM"."FLASHBACK_TRANSACTION_QUERY_TS" set "NAME" = '小倩子' where ROWID = 'AAAVUzAABAAAVxpAAC';
2 update "SYSTEM"."FLASHBACK_TRANSACTION_QUERY_TS" set "NAME" = '小优子' where ROWID = 'AAAVUzAABAAAVxpAAB';
3 update "SYSTEM"."FLASHBACK_TRANSACTION_QUERY_TS" set "NAME" = '小游子' where ROWID = 'AAAVUzAABAAAVxpAAA';
2.4 Flashback Table
- Restore the amount of data deleted by delete
- Need to enable row migration
- Note the time retained in undo_retention
Basic data:
CREATE TABLE flashback_table_test (
ID NUMBER,
NAME VARCHAR2(30)
);
INSERT INTO flashback_table_test (ID, NAME) VALUES(1, '瑶瑶');
INSERT INTO flashback_table_test (ID, NAME) VALUES(2, '倩倩');
INSERT INTO flashback_table_test (ID, NAME) VALUES(3, '优优');
COMMIT;
Flashback table demo:
-- 先查询
SELECT t.*, ROWID FROM flashback_table_test t;
SELECT to_char(SYSDATE, 'YYYY-MM-HH hh24:mi:ss:mm') 时间,
timestamp_to_scn(SYSDATE) scn
FROM dual;
-- 再删除
DELETE FROM flashback_table_test t WHERE t.id = 2;
COMMIT;
-- 闪回命令 start
ALTER TABLE flashback_table_test ENABLE ROW MOVEMENT; -- 打开表的行移动(重新生成 rowid)
FLASHBACK TABLE flashback_table_test TO SCN 12442453;
-- 闪回命令 end
SELECT t.*, ROWID FROM flashback_table_test t;
2.5 Flashback delete
- Recoverable: Table deleted using drop
- Can not be restored: the table under the administrator user (such as: system, sys) or truncate table
grammar:
FLASHBACK TABLE table_name
TO BEFORE DROP [RENAME TO table_name2] -- 删除表同时修改 表名
[ENABLE|DISABLE] triggers; -- 删除表的同时,启用|禁用 触发器
Basic data preparation:
CREATE TABLE scott.flashback_drop_test (
ID NUMBER,
NAME VARCHAR2(30)
);
SELECT * FROM scott.flashback_drop_test;
DROP TABLE scott.flashback_drop_test;
Case 1: General flashback
SELECT * FROM dba_recyclebin t WHERE t.owner = 'SCOTT'; -- 或 user_recyclebin
FLASHBACK TABLE scott.flashback_drop_test TO BEFORE DROP;
Case 2: The table name in the recycle bin already exists in the database (duplicate name):
- Solution: Rename
SELECT * FROM dba_recyclebin t WHERE t.owner = 'SCOTT' ORDER BY t.droptime DESC; -- 或 user_recyclebin
方式1:
FLASHBACK TABLE scott.flashback_drop_test TO BEFORE DROP RENAME TO flashback_drop_test2;
方式2:(推荐,防止 "一张表,多次删除" 的情况)
-- SELECT * FROM scott."BIN$hr4mmwLmTAyvSvOcqvFO+A==$0";
FLASHBACK TABLE scott."BIN$hr4mmwLmTAyvSvOcqvFO+A==$0" TO BEFORE DROP RENAME TO flashback_drop_test3;
Situation 3: One table, multiple deletions
- Please note: the restored table is the last deleted table
Basic data preparation:
CREATE TABLE scott.flashback_drop_test (
ID NUMBER,
NAME VARCHAR2(30)
);
DROP TABLE scott.flashback_drop_test;
-- 以上 创建、删除 至少操作 2 次,方便演示
SELECT * FROM user_recyclebin t ORDER BY t.droptime DESC;
Demo:
FLASHBACK TABLE flashback_drop_test TO BEFORE DROP;
3 expansion
1. 显示回收站(sqlplus 命令)
> show recyclebin
2. 清空回收站(sqlplus 命令)
> purge recyclebin
3. 查询回收站
select * from dba_recyclebin; -- user_recyclebin
4. 删除表并在回收站中清空
drop table table_name purge;
5. 清空表数据并在回收站中清空
truncate table table_name;