oracle_How to Recover Data (Without a Backup!)
How to Recover Data (Without a Backup!)
It's the classic career-limiting maneuver(职业限制机动): accidentally deleting data you weren't meant to. It's easy to do this as the result of mistakes such as:
- Running a test script on production
- Getting the where clause wrong for a delete
Doing this in test or dev is likely to bring the ire (烦恼)of your colleagues in IT. Do this in production and key parts of the business may come to a stop!
In either case you'll want to get your data back as quickly as possible.
Restoring from backup can be a time consuming process. Time you don't have in extreme cases.
Luckily Oracle can help you recover from many mistakes quickly - without needing a backup! In this post we'll look at how to undo the damage in the following cases:
- Restore a Whole Table
- Recover a Few Rows
- Recover a Few Rows++
- Restore Dropped Tables
- Revert the Whole Database!
Ready? Let's begin!
How to Restore a Whole Table
It's a classic rookie(新成员) mistake: running a delete without a where clause. And then committing it!
Here you need to recover all the data. Using Flashback Table, you can return a whole table to an earlier state. All you need to do is run:
flashback table <table> to timestamp <when it was good>;
For example, execute:
flashback table orders to timestamp systimestamp - interval '1' hour; hour instead of minute;
And Oracle restores the table its state one hour ago. Handy(搞定) if you’ve just deleted all the rows!
To use this, you must enable row movement:
alter table <table> enable row movement;
If you haven’t done this, you’ll get the following error:
ORA-08189: cannot flashback the table because row movement is not enabled
This is great if you’ve accidentally deleted or updated the whole table. But if there are only a handful of (少数)rows you need to recover it’s excessive(过度的,夸张). You’ve used stick of dynamite(zhayao棒
) to kill an ant.(大材小用)
Even if you need to recover a large section of a table, flashing it back loses any changes made after the time you’re restoring it to. In most production systems there will be new rows you want to keep!
So this is handy for worst-case scenarios. It’s also useful for returning a table to a known state after testing. But for small finger trouble issues, it’s more likely you need to recover a handful of rows.
How to Recover a Few Rows
So what do you do if there are a small number of rows you need to restore? Clearly Flashback Table is overkill(过度的杀伤威力). You need something more nuanced(细微差别的).
Enter Flashback Query. This enables you see the contents of table at a point in time in the past. To do this you just add the “as of” clause after your table.
To see it at a given time, use "as of timestamp". For example, to see how it looked one hour ago, use:
select * from <table> as of timestamp systimestamp - interval '1' hour;
Or you can use a database SCN with:
select * from <table> as of scn 1234567;
Salvaging(抢救) the Deleted Rows
If you know which rows were removed, add the appropriate where clause to your SQL. Then pass the result of this to an insert. For example:
insert into table_name
select * from <table_name> as of timestamp sysdate – interval '1' hour
where <conditions to find the rows>;
And you’ll have your missing data back!
If you’re not sure which rows are gone, you can find the deleted ones using minus(减去). This enables you to compare the current state of the table how it looked before the time of the disaster. The SQL find rows which were in the table an hour ago, but not anymore is:
select * from <table> as of timestamp sysdate – interval '1' hour
minus
select * from <table>;
To recover these, insert the result of this query!
insert into <table>
select * from <table> as of timestamp sysdate – interval '1' hour note:sysdate word:if show error you can manul input it.
minus
select * from <table>;
Note this will include all rows deleted in the past hour. If there are genuine(真实的) deletions, you’ll need to remove them again.
Recover Overwritten Values
What if the rows weren’t deleted, just updated? And you need to restore the original values, but don’t know what they are?
Then you can use Flashback Query in an update too:
update <table> cur
set (col1, col2, col3) = (
select col1, col2, col3 from <table>
as of timestamp systimestamp – interval '1' hour old
where cur.primary_key = old.primary_key
)
where <rows to update>;
update emp04 cur
set (deptno) = (
select deptno from emp04
as of timestamp systimestamp - interval '' MINUTE OLD
where cur.empno = old.empno
) WHERE empno=;
This is fantastic. But Flashback Query has a couple of limitations:
- Oracle only ensures you can query as far back as the value of your “undo_retention” parameter.
- Oracle is unable to query across many forms of DDL. So if you change a table's structure there's a good chance Flashback Query will fail.
By default the undo retention is 900 seconds. That’s just 15 minutes. Unless you’re quick there’s a good chance you’ll miss this window in busy production systems.
You can overcome this by increasing the retention time. For example, to increase it to one day, run:
alter system set undo_retention = 86400 scope = both;
Take care before doing this. Oracle uses the undo tablespace to run flashback queries. So increasing the retention means you’ll need to make this larger to support flashback. This could lead to a big jump in storage requirements.
The second problem normally rears (饲养)its head after releases. If you’ve run DDL against a table, there's a good chance you’ll get:
ORA-01466: unable to read data - table definition has changed
This is frustrating(产生挫折的). It’s useful to be able to compare a table before and after a release. Particularly when something’s gone wrong! If you can compare the before and after states of the table it can make diagnosis simple.
Also note that truncate is DDL in Oracle. So if you’ve used this method to wipe a table, there’s no way back!
Fortunately, you can overcome both of these issues.
How to Recover a Few Rows++
Flashback Data Archive powers up Flashback Query. It does this by storing the changes in tables. This means you have a permanent store instead of relying on undo.
To use this, first you need to create an archive. You can do this with the following SQL:
create flashback archive <archive> tablespace <tablespace> retention 1 year;
The retention clause states how long you want to keep your history. You can specify this as a number of days, months or years.
Once you have the archive in place, simply alter your tables to use it:
alter table <table> flashback archive <archive>;
And you’re done!
You can then recover data using the same method described above. But with the bonuses(红利) of:
- Being able to query across DDL
- Having a larger window of time to recover data
One word of caution: when you enable it, Oracle creates history tables. It does this in a background process. So this setup can fail without giving you an error. Be sure to check this is working before you rely on it!
So far we’ve looked at recovering rows. But what happens if you drop a table?! Can flashback help here?
How to Restore Dropped Tables
In 10g, Oracle introduced the recyclebin. Just like the recyclebin in your “favourite” OS, you can recover objects placed in here. To do so, simply run: flashback table <table> to before drop; And you’ll have your table back! You can view the contents of the recyclebin with this SQL: select * from recyclebin; To see the names of tables you’ve dropped, check original_name. This only contains objects your user owned. If you have the appropriate permissions, you can query dba_recyclebin. This enables you to see dropped objects for all users. |
By Users Cbuckley, Jpowell on en.wikipedia [Public domain], via Wikimedia Commons |
Tables in the recyclebin still consume space. If you’re sure you want to permanently drop a table, use the purge option:
drop table <table> purge;
And the table is gone for good. Or you if you want a safety net, drop it normally. Then remove it from the recyclebin with:
purge table <table>;
If you want to recover all the space the recyclebin is using, clear it out with:
purge recyclebin;
And it’s empty!
Note that the recyclebin only applies when you use drop table. If you take other actions that remove tables, e.g. drop user or drop tablespace, they are gone for good(他们将永远不再).
These solutions are all great if you’re dealing with a single table. But what if something more serious has happened? What if someone managed to run a truncate cascade wiping out your whole database?
Individually recovering tables could take some time.
How to Revert the Whole Database
If someone has accidentally or maliciously has trashed your data, figuring out what to restore could be a long process. With Flashback Database, you can restore a whole database back to an earlier time.
Oracle enables this with flashback logs. It stores these in the fast recovery area.
To use Flashback Database you need to do some initial setup. There are two ways to enable this:
- Enable Flashback Database
- Create a restore point
Enable Flashback Database
Firstly, your database must be running in archivelog mode. Assuming this is the case, the process for enabling it is:
- Configure the fast recovery area
- Set the DB_flashback_retention_target parameter (optional)
- Enable Flashback Database
For step one, you need to set a couple of parameters. These are DB_RECOVERY_FILE_DEST_SIZE and DB_RECOVERY_FILE_DEST. These control how much space there is available for the logs and where they go respectively. For example:
alter system set DB_RECOVERY_FILE_DEST = '/u01/oradata/recovery_area' scope=both;
alter system set DB_RECOVERY_FILE_DEST_SIZE = 10G scope=both;
Set DB_flashback_retention_target to give the upper limit for how far back you can flashback the database. This is specified in minutes. So to set a maximum duration of one week, run:
alter system set DB_flashback_retention_target = 10080 scope=both;
Just ensure that you set the DB_RECOVERY_FILE_DEST_SIZE large enough to support this! For further discussion about this, check the docs.
The final step is simple. Just run:
alter database flashback on;
And you're done!
Note that enabling this adds some overhead. Oracle must log all changes you make to the data. So the more inserts, updates and deletes you have the greater the overhead.
Create a Restore Point
Doing this is easy. Simply run:
create restore point <restore_point> guarantee flashback database;
The guarantee clause is optional.
Without this, Oracle will age out old restore points. So you may be unable to go back to the time of a particular restore point.
With it, Oracle ensures you can always recover back to the time you created it. As with Flashback Database, Oracle stores the logs to support this in the fast recovery area.
To recover the space you must drop the restore point manually.
If you forget to do this then you can run out of space. And your database may grind to a halt!
This seems risky. So why would you want to create a guaranteed restore point?
Two key use cases for this are:
- An extra safety net for database releases
- Reverting test databases to a known state
Database releases are notoriously(众所周知地) difficult to undo. Especially if you’ve dropped columns or other breaking schema changes. Flashing back is quicker and easier than unpicking the errors if you have unexpected failures.
Using a guaranteed restore point ensures you have this fall back. With a normal restore point, you may find it was aged out in the release process. Just ensure you have monitoring on your Fast Recovery Area.
Reverting a database after running tests another great use case. As with releases, undoing the changes can be time consuming and tricky(狡猾的).
Restore points make it easy to reset after test runs. Instead of worrying about how to get back to the original state, just flashback once they’re complete!
This is super handy when it comes to preparing and testing release scripts. Writing the scripts for complex upgrades can take a few tries to get right. Being able to flashback the database after each try is a huge time saver.
Flashback Database could also form part of your Continuous Integration and DevOps strategies. Just build a script to flash the database back after each test run.
In any case, ensure you have a process for removing guaranteed restore points. Without this you may find your job finishes as quickly as your database does!
Flashing Back a Database
With a restore point in place or flashback enabled you’re all set! If disaster strikes, you can return to a point in the past by:
shutdown immediate startup mount alter database open resetlogs;
And you’re done! |
benluna12 / Pixabay |
If you want to take extra care(额外的照顾), you can open the database in read only mode. Do this between steps three and four above. If you do, you must restart the database in mount mode before opening it with resetlogs.
Summary
The term Flashback in Oracle covers a number of technologies. All these serve the goal of enabling you to return to a previous state quickly and easily. If you want more details on these, check out the following sections of the docs:
- Using Oracle Flashback Technology
- Using Flashback Database and Restore Points
- Performing Flashback and Database Point-in-Time Recovery
For examples of Flashback Table, Query and Drop in action, check this script in LiveSQL.
Flashback in its various forms has saved me many times in my career. The situations ranged from restoring rows mistakenly deleted by users to recovering tables dropped by accidentally running test scripts against production!
Flashback is great for overcoming these accidental mishaps(灾祸). But there are some things it can’t recover from. For example, people deleting database files in the OS. There’s no substitute(代替, 替换, 代用) for full protection.
Remember, always have a backup!
How about you? Has flashback has saved you or your users at any time?
If so, please let us know in the comments!
* Applies to Basic Flashback Archive only. Optimization requires EE license and the Advanced Compression Option. To use Flashback Data Archive in 11.2.0.3 and earlier you had to purchase the relevant option.
Join the discussion
oracle_How to Recover Data (Without a Backup!)的更多相关文章
- 谈谈WCF中的Data Contract(3):WCF Data Contract对Collection & Dictionary的支持
谈谈WCF中的Data Contract(3):WCF Data Contract对Collection & Dictionary的支持 在本篇文章上一部分Order Processing的例 ...
- Hadoop Datanode节点无法启动(All directories in dfs.data.dir are invalid)
Hadoop Datanode节点无法启动(All directories in dfs.data.dir are invalid) java.io.IOException: All director ...
- mysql中的备份(backup)和恢复(recovery)
(一)备份类型(backup type) 物理和逻辑备份(Physical Versus Logical Backup) 物理备份是指直接复制存储数据库内容的目录和文件,这种类型的备份适用于出现问题时 ...
- Android开发教程 - 使用Data Binding(七)使用BindingAdapter简化图片加载
本系列目录 使用Data Binding(一)介绍 使用Data Binding(二)集成与配置 使用Data Binding(三)在Activity中的使用 使用Data Binding(四)在Fr ...
- Android开发教程 - 使用Data Binding(八)使用自定义Interface
本系列目录 使用Data Binding(一)介绍 使用Data Binding(二)集成与配置 使用Data Binding(三)在Activity中的使用 使用Data Binding(四)在Fr ...
- Android开发教程 - 使用Data Binding(五)数据绑定
本系列目录 使用Data Binding(一)介绍 使用Data Binding(二)集成与配置 使用Data Binding(三)在Activity中的使用 使用Data Binding(四)在Fr ...
- Android开发教程 - 使用Data Binding(六)RecyclerView Adapter中的使用
本系列目录 使用Data Binding(一)介绍 使用Data Binding(二)集成与配置 使用Data Binding(三)在Activity中的使用 使用Data Binding(四)在Fr ...
- Android开发教程 - 使用Data Binding(四)在Fragment中的使用
本系列目录 使用Data Binding(一)介绍 使用Data Binding(二)集成与配置 使用Data Binding(三)在Activity中的使用 使用Data Binding(四)在Fr ...
- Android开发教程 - 使用Data Binding(三)在Activity中的使用
本系列目录 使用Data Binding(一)介绍 使用Data Binding(二)集成与配置 使用Data Binding(三)在Activity中的使用 使用Data Binding(四)在Fr ...
随机推荐
- webApi的控制台服务
1.新建console项目,引用 下面包 2.新建Controller public class UserController : ApiController { public IEnumerable ...
- 什么是javascript的中间件?
第一次写博客,有点想在博客园试水的感觉,也分享下觉得有用的东西(源码自己写的) 什么是javascript中间件呢?函数middle就是用来构建中间件的,我用例子说明下 下面我定义了一个函数use,在 ...
- MyBatis模糊查询相关
Mybatis模糊查询的实现不难,如下实例:在UserMapper.xml中根据用户名模糊查询用户: <!-- 模糊查询用户 --> <select id="findSom ...
- BeautifulSoup库应用实例
获取博客园本人的积分排名数据: 1. 抓包获取积分排名数据返回接口:http://www.cnblogs.com/belle-ls/mvc/blog/sidecolumn.aspx?blogApp=b ...
- PIE SDK打开栅格数据
1. 功能简介 GIS将地理空间数据表示为矢量数据和栅格数据.矢量数据模型使用点.线和多边形来表示具有清晰空间位置和边界的空间要素,如控制点.河流和宗地等,每个要素被赋予一个ID,以便与其属性相关联. ...
- 图解 TCMalloc
https://zhuanlan.zhihu.com/p/29216091 图解 TCMalloc hellocode 永远年轻 693 人赞了该文章 前言 TCMalloc 是 Google 开 ...
- C#中if和#if区别
if的作用是程序流控制,会直接编译.执行.#if是对编译器的指令,其作用是告诉编译器,有些语句行希望在条件满足时才编译. --------------------------------------- ...
- 案例46-crm练习客户登录
1 login.jsp代码 <%@ page language="java" contentType="text/html; charset=UTF-8" ...
- Unity3D 发布成PC端常用设置
本文,基于Unity 5.6pro版本来发布PC端.文中若有不妥之处,欢迎各位指出! 一.如何去掉Unity官方水印? 首先,你需要pro版本的Unity3D.如果,你是personal版本的话,就需 ...
- pat1007. Maximum Subsequence Sum (25)
1007. Maximum Subsequence Sum (25) 时间限制 400 ms 内存限制 65536 kB 代码长度限制 16000 B 判题程序 Standard 作者 CHEN, Y ...