1 方便起见一般:执行如下即可不用往下看: 2 3 4 ① 启用行移动功能 5 6 alter table tbl_a enable row movement; 7 8 ② 闪回表数据到某个时间点 9 10 flashback table tbl_a to timestamp to_timestamp('2013-07-19 15:10:00','yyyy-mm-dd hh24:mi:ss'); 11 12 详解: 13 14 15 利用ORACLE的闪回功能恢复数据 16 17 一、 闪回表数据 18 19 20 从9i开始,Oracle提供了闪回(FLASHBACK)功能。使用FLASHBACK TABLE语句从撤消段中(undo segment)读取该表的过去映像,并利用Oracle9i中引入的回闪查询重建表行。UNDO_RETENTION给出了闪回支持的最小时间。也就是说,FLASHBACK最少可以支持UNDO_RETENTION给出的时间,如果系统比较闲,则可以闪回更长的时间。(当然,如果回滚表空间的空间分配不足,当系统处于忙时,有可能重用还没有达到UNDO_RETENTION时间限制的数据的空间)。使用闪回的一个前提是表不能进行DDL操作。不但不能对DDL操作进行回闪,而且,也无法闪回到DDL操作以前的数据了。 21 22 23 SQL> select * from v$version; 24 25 26 BANNER 27 28 ---------------------------------------------------------------- 29 30 31 Oracle Database 10g Enterprise Edition Release 10.2.0.1.0 - Prod 32 33 34 PL/SQL Release 10.2.0.1.0 - Production 35 36 37 CORE 10.2.0.1.0 Production 38 39 40 TNS for 32-bit Windows: Version 10.2.0.1.0 - Production 41 42 43 NLSRTL Version 10.2.0.1.0 – Production 44 45 46 --获得系统变更号 47 48 49 C:\Documents and Settings\linyuefeng>sqlplus /nolog 50 51 52 SQL*Plus: Release 10.2.0.1.0 - Production on 星期四 10月 26 20:41:28 2006 53 54 55 Copyright (c) 1982, 2005, Oracle. All rights reserved. 56 57 58 SQL> conn scott/scott@ora10g; 59 60 61 已连接。 62 63 64 SQL> var scn number 65 66 67 SQL> exec :scn :=dbms_flashback.get_system_change_number 68 69 70 PL/SQL 过程已成功完成。 71 72 73 SQL> print scn 74 75 76 SCN 77 78 79 ---------- 80 81 82 914958 83 84 85 SQL> select count(*) from emp; 86 87 88 COUNT(*) 89 90 91 ---------- 92 93 94 14 95 96 97 SQL> delete from emp; 98 99 100 已删除14行。 101 102 103 SQL> select count(*) from emp; 104 105 106 COUNT(*) 107 108 109 ---------- 110 111 112 0 113 114 115 SQL> commit; 116 117 118 提交完成。 119 120 121 SQL> select count(*) from emp as of scn :scn; 122 123 124 COUNT(*) 125 126 127 ---------- 128 129 130 14 131 132 133 SQL> flashback table emp to scn :scn; 134 135 136 flashback table emp to scn :scn 137 138 139 * 140 141 142 第 1 行出现错误: 143 144 145 ORA-08189: 因为未启用行移动功能, 不能闪回表 146 147 148 SQL> alter table emp enable row movement; 149 150 151 表已更改。 152 153 154 这个命令的作用就是允许ORACLE修改分配给行的rowid。在ORACLE中,插入一行时就会为它分配一个rowid,而且这一行永远拥有这个rowid。闪回表处理时会对EMP表完成DELETE 操作,并且重新插入行,这样就会为这些行分配一个新的rowid。要支持闪回功能就必须允许ORACLE执行这个操作。 155 156 157 SQL> flashback table emp to scn :scn; 158 159 160 闪回完成。 161 162 163 SQL> select count(*) from emp; 164 165 166 COUNT(*) 167 168 169 ---------- 170 171 172 14 173 174 175 ---也可以通过时间进行闪回 176 177 178 SQL> select to_char(sysdate,'yyyy-mm-dd hh24:mi:ss') TIME from dual; 179 180 181 TIME 182 183 184 ------------------- 185 186 187 2006-10-26 20:55:48 188 189 190 SQL> select count(*) from emp; 191 192 193 COUNT(*) 194 195 196 ---------- 197 198 199 14 200 201 202 SQL> delete from emp; 203 204 205 已删除14行。 206 207 208 SQL> commit; 209 210 211 提交完成。 212 213 214 SQL> flashback table emp to timestamp to_date('2006-10-26 20:55:48','yyyy-mm-dd 215 216 217 hh24:mi:ss'); 218 219 220 闪回完成。 221 222 223 SQL> select count(*) from emp; 224 225 226 COUNT(*) 227 228 229 ---------- 230 231 232 14 233 234 235 二、 闪回删除的表 236 237 238 flashback drop特性从Oracle10g开始才有的,这个新特性,允许你从当前数据库中恢复一个被drop了的对象。在执行drop操作时,现在Oracle不是真正删除它,而是将该对象自动将放入回收站(一个虚拟的容器,用于存放所有被删除的对象)。对于一个对象的删除,ORACLE的操作仅仅就是简单的重令名而已。 239 240 241 在回收站中,被删除的对象将占用创建时的同样的空间,可以利用flashback功能来恢复它, 这个就是flashback drop功能。 242 243 244 SQL> create table emp_test as select * from emp; 245 246 247 Table created 248 249 250 SQL> drop table emp_test; 251 252 253 Table dropped 254 255 256 当一个表被删除并移动到"回收站"中,它的名字要进行一些转换。这样的目的显而易见是为了避免同类对象名称的重复。 257 258 259 SQL> select owner,object_name,original_name,DROPTIME from dba_recyclebin order by droptime; 260 261 262 OWNER OBJECT_NAME ORIGINAL_NAME DROPTIME 263 264 265 ------------------------------ ------------------------------ 266 267 268 SCOTT BIN$rtpdTNe6SIysmO+ZB0t3aQ==$0 EMP_TEST 2006-10-26:22:23:06 269 270 271 SQL> create table emp_test as select * from emp; 272 273 274 Table created 275 276 277 SQL> drop table emp_test; 278 279 280 Table dropped 281 282 283 SQL> select owner,object_name,original_name, DROPTIME from dba_recyclebin order by droptime; 284 285 286 OWNER OBJECT_NAME ORIGINAL_NAME DROPTIME 287 288 289 ------------------------------ ------------------------------ 290 291 292 SCOTT BIN$rtpdTNe6SIysmO+ZB0t3aQ==$0 EMP_TEST 2006-10-26:22:23:06 293 294 295 SCOTT BIN$roQhkx6tQneThvaRlsjrhw==$0 EMP_TEST 2006-10-26:22:23:50 296 297 298 --使用flashback table 进行恢复,默认恢复最近删除的表 299 300 301 SQL> flashback table emp_test to before drop; 302 303 304 Done 305 306 307 SQL> select owner,object_name,original_name,DROPTIME from dba_recyclebin order by droptime; 308 309 310 OWNER OBJECT_NAME ORIGINAL_NAME DROPTIME 311 312 313 ------------------------------ ------------------------------ 314 315 316 SCOTT BIN$rtpdTNe6SIysmO+ZB0t3aQ==$0 EMP_TEST 2006-10-26:22:23:06 317 318 319 --也可以指定表名进行恢复 320 321 322 SQL> flashback table "BIN$rtpdTNe6SIysmO+ZB0t3aQ==$0" to before drop; 323 324 325 flashback table "BIN$rtpdTNe6SIysmO+ZB0t3aQ==$0" to before drop 326 327 328 ORA-38312: 原始名称已被现有对象使用 329 330 331 此时被恢复的表名称仍然采用以前的名字,我们之前已经恢复一次EMP_TEST,所以现在恢复就出现了重名,不过可以为其指定新的名字。 332 333 334 SQL> flashback table "BIN$rtpdTNe6SIysmO+ZB0t3aQ==$0" to before drop rename to emp_test2; 335 336 337 Done 338 339 340 SQL> select table_name from user_tables where table_name like '%EMP_TEST%'; 341 342 343 TABLE_NAME 344 345 346 ------------------------------ 347 348 349 EMP_TEST 350 351 352 EMP_TEST2 353 354 355 --删除回收站里的对象,不能使用DROP命令进行删除,必须使用PURGE命令 356 357 358 SQL> drop table emp_test; 359 360 361 Table dropped 362 363 364 SQL> drop table emp_test2; 365 366 367 Table dropped 368 369 370 SQL> select owner,object_name,original_name,DROPTIME from dba_recyclebin order by droptime; 371 372 373 OWNER OBJECT_NAME ORIGINAL_NAME DROPTIME 374 375 376 ------------------------------ ------------------------------ 377 378 379 SCOTT BIN$M4Q0Pb94SOWSFGarOpI5Og==$0 EMP_TEST 2006-10-26:22:46:07 380 381 382 SCOTT BIN$7P+osQdjSs+5CcSXBc0NAA==$0 EMP_TEST2 2006-10-26:22:46:10 383 384 385 SQL> drop table "BIN$M4Q0Pb94SOWSFGarOpI5Og==$0"; 386 387 388 drop table "BIN$M4Q0Pb94SOWSFGarOpI5Og==$0" 389 390 391 ORA-38301: 无法对回收站中的对象执行 DDL/DML 392 393 394 395 SQL> purge table "BIN$M4Q0Pb94SOWSFGarOpI5Og==$0"; 396 397 398 Done 399 400 SQL> select owner,object_name,original_name,DROPTIME from dba_recyclebin order by droptime; 401 402 403 OWNER OBJECT_NAME ORIGINAL_NAME DROPTIME 404 405 406 ------------------------------ ------------------------------ 407 408 409 SCOTT BIN$7P+osQdjSs+5CcSXBc0NAA==$0 EMP_TEST2 2006-10-26:22:46:10 410 411 412 --删除整个回收站里的对象 413 414 415 SQL> purge recyclebin; 416 417 418 Done 419 420 421 SQL> select owner,object_name,original_name,DROPTIME from dba_recyclebin order by droptime; 422 423 424 OWNER OBJECT_NAME ORIGINAL_NAME DROPTIME 425 426 427 ------------------------------ ------------------------------ 428 429 430 未选定行