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:

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
Best of all, as of 11.2.0.4, Flashback Data Archive is free*!

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:

  1. Configure the fast recovery area
  2. Set the DB_flashback_retention_target parameter (optional)
  3. 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;
  1. Shutting down the database:
  2. Starting it up in mount mode
  3. Running flashback:
    flashback database to scn 12345;
    flashback database to time
    "to_date('01/01/2016', 'dd/mm/yyyy')";
    flashback database to restore point <restore_point><restore_point>;
    1. To an SCN
    2. To a point in time
    3. To a restore point
  4. Reopen the database with 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:

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!)的更多相关文章

  1. 谈谈WCF中的Data Contract(3):WCF Data Contract对Collection & Dictionary的支持

    谈谈WCF中的Data Contract(3):WCF Data Contract对Collection & Dictionary的支持 在本篇文章上一部分Order Processing的例 ...

  2. 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 ...

  3. mysql中的备份(backup)和恢复(recovery)

    (一)备份类型(backup type) 物理和逻辑备份(Physical Versus Logical Backup) 物理备份是指直接复制存储数据库内容的目录和文件,这种类型的备份适用于出现问题时 ...

  4. Android开发教程 - 使用Data Binding(七)使用BindingAdapter简化图片加载

    本系列目录 使用Data Binding(一)介绍 使用Data Binding(二)集成与配置 使用Data Binding(三)在Activity中的使用 使用Data Binding(四)在Fr ...

  5. Android开发教程 - 使用Data Binding(八)使用自定义Interface

    本系列目录 使用Data Binding(一)介绍 使用Data Binding(二)集成与配置 使用Data Binding(三)在Activity中的使用 使用Data Binding(四)在Fr ...

  6. Android开发教程 - 使用Data Binding(五)数据绑定

    本系列目录 使用Data Binding(一)介绍 使用Data Binding(二)集成与配置 使用Data Binding(三)在Activity中的使用 使用Data Binding(四)在Fr ...

  7. Android开发教程 - 使用Data Binding(六)RecyclerView Adapter中的使用

    本系列目录 使用Data Binding(一)介绍 使用Data Binding(二)集成与配置 使用Data Binding(三)在Activity中的使用 使用Data Binding(四)在Fr ...

  8. Android开发教程 - 使用Data Binding(四)在Fragment中的使用

    本系列目录 使用Data Binding(一)介绍 使用Data Binding(二)集成与配置 使用Data Binding(三)在Activity中的使用 使用Data Binding(四)在Fr ...

  9. Android开发教程 - 使用Data Binding(三)在Activity中的使用

    本系列目录 使用Data Binding(一)介绍 使用Data Binding(二)集成与配置 使用Data Binding(三)在Activity中的使用 使用Data Binding(四)在Fr ...

随机推荐

  1. java8 方法引用与lambda

    List<String> list = new ArrayList<>(); //list.stream().filter((String s)->System.out. ...

  2. drf之视图

    一.视图(视图函数) Django REST framwork 提供的视图的主要作用: 控制序列化器的执行(检验.保存.转换数据) 控制数据库查询的执行 1.请求与响应 1.request REST ...

  3. C++ GUI Qt4编程(08)-3.2spreadsheet-resource

    1. C++ GUI Qt4编程第三章,图片使用资源机制法. 2. 步骤: 2-1. 在resource文件夹下,新建images文件,存放图片. 2-2. 新建spreadsheet.qrc文件,并 ...

  4. PIE SDK专题制图切换模板

    1.    功能简介 专题图是突出且较完备的表示一种或几种自然或社会经济现象,从而使地图起到专门化的作用.与普通地图不同,专题图的表示内容丰富多彩,多种多样.在实际业务应用中经常会用同一张地图出很多个 ...

  5. JAVA实体类不要使用基本类型,基本类型包含byte、int、short、long、float、double、char、boolean

    由于JAVA的基本类型会有默认值,例如当某个类中存在private  int age;字段时,创建这个类时,age会有默认值0.当使用age属性时,它总会有值.因此在某些情况下,便无法实现age为nu ...

  6. twitter storm学习 - 安装部署问题汇总

    已经碰到的或者将来碰到的关于安装部署方面的问题以及解决方法,先挖个坑 1.提交的topology在admin界面上看emitted始终都是0,查看日志发现有如下错误: worker [ERROR] E ...

  7. (转)python strip()函数 去空格\n\r\t函数的用法

    原文:http://www.cnblogs.com/zdz8207/p/python_learn_note_20.html python3.4学习笔记(二十) python strip()函数 去空格 ...

  8. 一些Andoid studio常用的快捷键

    常用快捷键    Android Studio是基于IntelliJ IDEA的,我们都知道,IDEA是一个很方便很好用的IDE,其中有许多快捷键,但是太多快捷键我们也记不住. 其实,我们可以记住几个 ...

  9. TOJ 1885 Triangles

    Description It is always very nice to have little brothers or sisters. You can tease them, lock them ...

  10. python 生成、删除、拷贝目录

    1. 生成目录 函数原型:distutils.dir_util.mkpath(name[, mode=0777, verbose=0, dry_run=0]) from distutils impor ...