ArcSDE for Oracle怎么恢复误删除的要素类和要素

其实并不希望用户都来浏览这篇文章,如果是自己学习还好,如果是出现问题了,可能就比较麻烦了。 经常会有用户咨询我们,我不小心删除了ArcSDE里面的相关表,或者删除了相关记录,导致ArcSDE服务、连接、编辑等出现的相关问题,先不说这些问题怎么解决, 对

其实并不希望用户都来浏览这篇文章,如果是自己学习还好,如果是出现问题了,可能就比较麻烦了。


经常会有用户咨询我们,我不小心删除了ArcSDE里面的相关表,或者删除了相关记录,导致ArcSDE服务、连接、编辑等出现的相关问题,先不说这些问题怎么解决,对出现这种现象就应该坚决杜绝,老有许多用户属于那种不知道事大事小,什么都敢亲身实践,虽然他们知道“实践是检验真理的唯一途径”,但是如果你不了解数据库或者ArcSDE的相关原理,你就自认为的操作,出现问题负责任的肯定是自己。之所以说这些还是希望用户不要擅自操作,数据库一旦挂了,前端再高效再炫的客户端也是白搭啊。


虽然这篇文章的题目是恢复ArcSDE的要素类和要素,但是我并没有真正的在ArcSDE里面做例子,或者但是我以oracle的删除表和删除记录为例作测试,至于ArcSDE,那么就需要用户了解ArcSDE的表结构之后,做相关的解决了,我也会给用户进行相关的说明。


删除记录的恢复

测试场景:我删除sde用户下table_locks里面的若干记录,然后恢复


操作步骤:

需要用户以管理员身份登录

1:查看table_locks,然后删除,提交

SQL> select * from sde.table_locks;

    SDE_ID REGISTRATION_ID LO
---------- --------------- --
      2031             179 S
      2031             192 S
      2010             179 S
      2010             192 S


SQL> delete  from sde.table_locks where sde_id=2010;

已删除2行。

SQL> commit;

提交完成。

SQL> select * from sde.table_locks;

    SDE_ID REGISTRATION_ID LO
---------- --------------- --
      2031             179 S
      2031             192 S
相关原理:SCN

SCN: System Change Number
SCN是顺序递增的一个数字,在Oracle 中用来标识数据库的每一次改动,及其先后顺序。SCN的最大值是0xffff.ffffffff。

Oracle对SCN的管理(RAC环境就由DBA来管理吧)
单节点的instance中,SCN值存在SGA区,由system commit number latch保护。任何进程要得到当前的SCN值,都要先得到这个latch。


SCN的机制
数据库运行时的SCN
我们先看下oracle事务中的数据变化是如何写入数据文件的:
1、 事务开始;
2、 在buffer cache中找到需要的数据块,如果没有找到,则从数据文件中载入buffer cache中;
3、 事务修改buffer cache的数据块,该数据被标识为“脏数据”,并被写入log buffer中;
4、 事务提交,LGWR进程将log buffer中的“脏数据”写入redo log file中;
5、 当发生checkpoint,CKPT进程更新所有数据文件的文件头中的信息,DBWr进程则负责将Buffer Cache中的脏数据写入到数据文件中。
Redo log中的high scn和low scn
Oracle的Redo log会顺序纪录数据库的各个变化。一组redo log文件写满后,会自动切换到下一组redo log文件。则上一组redo log的high scn就是下一组redo log的low scn。在current log中high scn为无穷大。
可通过查询v$log_history查看 low scn和 high scn。


更多了解:

http://czmmiao.iteye.com/blog/1010267

http://www.cnblogs.com/daduxiong/archive/2010/08/19/1803764.html

2:通过SCN的方法来恢复

--获得当前的SCN
SQL> select current_scn from v$database;

CURRENT_SCN
-----------
   19078853

--select * from sde.table_locks as of scn 19078843;
--确定删除的数据是否存在,如果存在,则恢复数据;如果不是,则继续缩小scn号

SQL> select * from sde.table_locks as of scn 19078830;

    SDE_ID REGISTRATION_ID LO
---------- --------------- --
      2031             179 S
      2031             192 S
      2010             179 S
      2010             192 S

--将table_locks闪回到前面的scn
SQL> flashback table  sde.table_locks to scn 19078830;
flashback table  sde.table_locks to scn 19078830
                     *
第 1 行出现错误:
ORA-08189: cannot flashback the table because row movement is not enabled

--这个命令的作用是,允许Oracle 修改分配给行的rowid。在Oracle 中,插入一行时就会为它分配一个rowid,而且这一行永远拥有这个rowid。闪回表处理会对EMP 完成DELETE,并且重新插入行,这样就会为这些行分配一个新的rowid。要支持闪回就必须允许Oracle 执行这个操作
SQL> alter table sde.table_locks enable row movement;

表已更改。



SQL> flashback table  sde.table_locks to scn 19078830;

闪回完成。

SQL> select * from sde.table_locks;

    SDE_ID REGISTRATION_ID LO
---------- --------------- --
      2031             179 S
      2031             192 S
      2010             179 S
      2010             192 S

3:使用时间恢复删除数据

以下信息仅供参考

1、查询当前系统时间
 
    select to_char(sysdate,'yyyy-mm-dd hh24:mi:ss') from dual;
 
  2、查询删除数据的时间点的数据
 
    select * from 表名 as of timestamp to_timestamp('2013-05-29 15:29:00','yyyy-mm-dd hh24:mi:ss');  (如果不是,则继续缩小范围)
 
  3、恢复删除且已提交的数据
 
    flashback table 表名 to timestamp to_timestamp('2013-05-29 15:29:00','yyyy-mm-dd hh24:mi:ss');


ArcSDE的建议:

我们上面演示的只针对单个表的记录删除的恢复,那么对ArcSDE来说

1:如果是非版本数据的编辑,就可以完全结合上面的例子直接恢复

2:如果是版本编辑的话,这个就需要用户去了解ArcSDE的版本表了。

至少用户需要对:基表、增量表、版本表(States、State_lineages、Versions等)进行闪回,而且如果是多用户并发编辑的话,状态表里面的数据就不仅仅是一个版本的信息,所以这个就比较麻烦。


可能有用户来说,其实版本编辑,误删除了,大不了重新编辑,或者不要这个版本的信息,反正我的default版本的数据并没有变化,恭喜你,如果你想到这一点,说明你对版本原理比较了解。


删除表的恢复

测试场景:drop一个数据库中的表对象,然后进行恢复


操作步骤:

对误删的表,只要没有使用PURGE永久删除选项,那么从flash back区恢复回来希望是挺大的。

1:删除一个表对象

SQL> select count(*) from test.a;

  COUNT(*)
----------
     33769

SQL> drop table test.a;

表已删除。

SQL> commit;

提交完成。

SQL> select count(*) from test.a;
select count(*) from test.a
                          *
第 1 行出现错误:
ORA-00942: ???????
2:使用闪回方法来恢复

原理:在Oracle数据库,用户删除的对象会存储在一个类似回收站的表里面,这些信息会在这个表里面进行存储,但是如果用户的删除操作比较多,这个表里面的信息会类似非归档日志,重新写入新的信息,如果那样的话就不好恢复了,所以出现问题,赶紧解决才是正道。

用户需要连接test用户,因为删除的表a属于该用户,查看回收表信息

SQL> select original_name,operation,type from recyclebin;

ORIGINAL_NAME                                                    OPERATION          TYPE
---------------------------------------------------------------- ------------------ --------------
D138                                                             DROP               TABLE
D138_IDX1                                                        DROP               INDEX
D138_PK                                                          DROP               INDEX
KEYSET_1247                                                      DROP               TABLE
KEYSET_1300                                                      DROP               TABLE
KEYSET_1301                                                      DROP               TABLE
KEYSET_1316                                                      DROP               TABLE
ARCGIS_SECURITY_USER_ROLE                                        DROP               TABLE
SYS_C0018056                                                     DROP               INDEX
ARCGIS_SECURITY_ROLES                                            DROP               TABLE
SYS_C0018067                                                     DROP               INDEX

ORIGINAL_NAME                                                    OPERATION          TYPE
---------------------------------------------------------------- ------------------ --------------
ARCGIS_SECURITY_USER_ROLE                                        DROP               TABLE
SYS_C0018070                                                     DROP               INDEX
ARCGIS_SECURITY_ROLES                                            DROP               TABLE
SYS_C0018074                                                     DROP               INDEX
ARCGIS_SECURITY_USER_ROLE                                        DROP               TABLE
SYS_C0018077                                                     DROP               INDEX
A                                                                DROP               TABLE
BIN$3fw3ulkOXtPgQKjApdwLHg==$0                                   DROP               INDEX
SYS_LOB0000094656C00018$$                                        DROP               LOB
SYS_IL0000094656C00018$$                                         DROP               LOB INDEX
我们可以看到有A名称的表,然后进行恢复即可
SQL> flashback table test.a to before drop;

闪回完成。

SQL> select count(*) from test.a;

  COUNT(*)
----------
     33769


但注意oracle( Release 10.2.0.1.0)回收站不支持系统表空间,如果删除的这个在系统表空间,这个表是不能闪回的


对表数据更新一段时间后,只有在初始化参数UNDO_RETENTION设置的时间内才可以查询到表flashback_transaction_query的数据更改记录。而且,只有初始化参数UNDO_MANAGEMENT设置为AUTO后才能使用闪回查询。


ArcSDE的建议:对ArcSDE来说也是一样

1:如果没有注册版本,如果使用ArcGIS客户端对要素类进行删除,我们可以看到数据库里面有

SQL> select original_name,operation,type from recyclebin where droptime='2013-05-31:12:25:41';

ORIGINAL_NAME                                                    OPERATION          TYPE
---------------------------------------------------------------- ------------------ --------------
A                                                                DROP               TABLE
SYS_LOB0000094656C00018$$                                        DROP               LOB
SYS_IL0000094656C00018$$                                         DROP               LOB INDEX
BIN$3fxefjQC5+rgQKjApdwUEQ==$2                                   DROP               INDEX
所以说,使用ArcMap删除不仅仅是要素类,还包含相关的索引对象还有其他,所以使用上面的方法可以只恢复同名表A,对ArcGIS10.1是没有问题的,完全可以通过桌面进行注册即可,对10版本之前的可能就有点小问题了,但是最主要的同名表恢复过来,我们可以通过sdelayer -o register方法注册也可以。


2:如果是注册版本

还是老样子,基表、增量表,ArcSDE的其他表的管理信息需要恢复记录(比如sde用户下table_regisertry会注册SDE库里面存储的要素类),那么使用数据库的方法闪回删除的要素类的同名表,类似这些注册信息的表的记录也需要进行操作。

也就是说,需要用户考虑基本和增量表的回复,其他的可以通过sdetable -o register将数据注册到ArcSDE中,通过Register as geodatabase将数据注册到Geodatabase中。


以上方法都是根据数据库的方式对ArcSDE的误操作进行一些简单的补救措施,仅供参考!


-------------------------------------------------------------------------------------------------------

-------------------------------------------------------------------------------------------------------